File: /usr/src/linux/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 (struct set_mtrr_context *ctxt)
382     {
383         unsigned long tmp;
384     
385         /*  Disable interrupts locally  */
386         __save_flags (ctxt->flags); __cli ();
387     
388         if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR )
389     	 return;
390     
391         /*  Save value of CR4 and clear Page Global Enable (bit 7)  */
392         if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) ) {
393     	ctxt->cr4val = read_cr4();
394     	write_cr4(ctxt->cr4val & (unsigned char) ~(1<<7));
395         }
396     
397         /*  Disable and flush caches. Note that wbinvd flushes the TLBs as
398     	a side-effect  */
399         {
400     	unsigned int cr0 = read_cr0() | 0x40000000;
401     	wbinvd();
402     	write_cr0( cr0 );
403     	wbinvd();
404         }
405     
406         if ( mtrr_if == MTRR_IF_INTEL ) {
407     	/*  Disable MTRRs, and set the default type to uncached  */
408     	rdmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
409     	wrmsr (MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
410         } else {
411     	/* Cyrix ARRs - everything else were excluded at the top */
412     	tmp = getCx86 (CX86_CCR3);
413     	setCx86 (CX86_CCR3, (tmp & 0x0f) | 0x10);
414     	ctxt->ccr3 = tmp;
415         }
416     }   /*  End Function set_mtrr_prepare  */
417     
418     /*  Restore the processor after a set_mtrr_prepare  */
419     static void set_mtrr_done (struct set_mtrr_context *ctxt)
420     {
421         if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR ) {
422     	 __restore_flags (ctxt->flags);
423     	 return;
424         }
425     
426         /*  Flush caches and TLBs  */
427         wbinvd();
428     
429         /*  Restore MTRRdefType  */
430         if ( mtrr_if == MTRR_IF_INTEL ) {
431     	/* Intel (P6) standard MTRRs */
432     	wrmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
433         } else {
434     	/* Cyrix ARRs - everything else was excluded at the top */
435     	setCx86 (CX86_CCR3, ctxt->ccr3);
436         }
437     
438         /*  Enable caches  */
439         write_cr0( read_cr0() & 0xbfffffff );
440     
441         /*  Restore value of CR4  */
442         if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
443     	write_cr4(ctxt->cr4val);
444     
445         /*  Re-enable interrupts locally (if enabled previously)  */
446         __restore_flags (ctxt->flags);
447     }   /*  End Function set_mtrr_done  */
448     
449     /*  This function returns the number of variable MTRRs  */
450     static unsigned int get_num_var_ranges (void)
451     {
452         unsigned long config, dummy;
453     
454         switch ( mtrr_if )
455         {
456         case MTRR_IF_INTEL:
457     	rdmsr (MTRRcap_MSR, config, dummy);
458     	return (config & 0xff);
459         case MTRR_IF_AMD_K6:
460     	return 2;
461         case MTRR_IF_CYRIX_ARR:
462     	return 8;
463         case MTRR_IF_CENTAUR_MCR:
464     	return 8;
465         default:
466     	return 0;
467         }
468     }   /*  End Function get_num_var_ranges  */
469     
470     /*  Returns non-zero if we have the write-combining memory type  */
471     static int have_wrcomb (void)
472     {
473         unsigned long config, dummy;
474         struct pci_dev *dev = NULL;
475         
476        /* ServerWorks LE chipsets have problems with  write-combining 
477           Don't allow it and  leave room for other chipsets to be tagged */
478     
479         if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
480     	switch(dev->vendor) {
481             case PCI_VENDOR_ID_SERVERWORKS:
482      	    switch (dev->device) {
483     	    case PCI_DEVICE_ID_SERVERWORKS_LE:
484     		return 0;
485     		break;
486     	    default:
487     		break;
488     	    }
489     	    break;
490     	default:
491     	    break;
492     	}
493         }
494     
495     
496         switch ( mtrr_if )
497         {
498         case MTRR_IF_INTEL:
499     	rdmsr (MTRRcap_MSR, config, dummy);
500     	return (config & (1<<10));
501     	return 1;
502         case MTRR_IF_AMD_K6:
503         case MTRR_IF_CENTAUR_MCR:
504         case MTRR_IF_CYRIX_ARR:
505     	return 1;
506         default:
507     	return 0;
508         }
509     }   /*  End Function have_wrcomb  */
510     
511     static u32 size_or_mask, size_and_mask;
512     
513     static void intel_get_mtrr (unsigned int reg, unsigned long *base,
514     			    unsigned long *size, mtrr_type *type)
515     {
516         unsigned long mask_lo, mask_hi, base_lo, base_hi;
517     
518         rdmsr (MTRRphysMask_MSR(reg), mask_lo, mask_hi);
519         if ( (mask_lo & 0x800) == 0 )
520         {
521     	/*  Invalid (i.e. free) range  */
522     	*base = 0;
523     	*size = 0;
524     	*type = 0;
525     	return;
526         }
527     
528         rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
529     
530         /* Work out the shifted address mask. */
531         mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT)
532     		| mask_lo >> PAGE_SHIFT;
533     
534         /* This works correctly if size is a power of two, i.e. a
535            contiguous range. */
536          *size = -mask_lo;
537          *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
538          *type = base_lo & 0xff;
539     }   /*  End Function intel_get_mtrr  */
540     
541     static void cyrix_get_arr (unsigned int reg, unsigned long *base,
542     			   unsigned long *size, mtrr_type *type)
543     {
544         unsigned long flags;
545         unsigned char arr, ccr3, rcr, shift;
546     
547         arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
548     
549         /* Save flags and disable interrupts */
550         __save_flags (flags); __cli ();
551     
552         ccr3 = getCx86 (CX86_CCR3);
553         setCx86 (CX86_CCR3, (ccr3 & 0x0f) | 0x10);		/* enable MAPEN */
554         ((unsigned char *) base)[3]  = getCx86 (arr);
555         ((unsigned char *) base)[2]  = getCx86 (arr+1);
556         ((unsigned char *) base)[1]  = getCx86 (arr+2);
557         rcr = getCx86(CX86_RCR_BASE + reg);
558         setCx86 (CX86_CCR3, ccr3);				/* disable MAPEN */
559     
560         /* Enable interrupts if it was enabled previously */
561         __restore_flags (flags);
562         shift = ((unsigned char *) base)[1] & 0x0f;
563         *base >>= PAGE_SHIFT;
564     
565         /* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7
566          * Note: shift==0xf means 4G, this is unsupported.
567          */
568         if (shift)
569           *size = (reg < 7 ? 0x1UL : 0x40UL) << (shift - 1);
570         else
571           *size = 0;
572     
573         /* Bit 0 is Cache Enable on ARR7, Cache Disable on ARR0-ARR6 */
574         if (reg < 7)
575         {
576     	switch (rcr)
577     	{
578     	  case  1: *type = MTRR_TYPE_UNCACHABLE; break;
579     	  case  8: *type = MTRR_TYPE_WRBACK;     break;
580     	  case  9: *type = MTRR_TYPE_WRCOMB;     break;
581     	  case 24:
582     	  default: *type = MTRR_TYPE_WRTHROUGH;  break;
583     	}
584         } else
585         {
586     	switch (rcr)
587     	{
588     	  case  0: *type = MTRR_TYPE_UNCACHABLE; break;
589     	  case  8: *type = MTRR_TYPE_WRCOMB;     break;
590     	  case  9: *type = MTRR_TYPE_WRBACK;     break;
591     	  case 25:
592     	  default: *type = MTRR_TYPE_WRTHROUGH;  break;
593     	}
594         }
595     }   /*  End Function cyrix_get_arr  */
596     
597     static void amd_get_mtrr (unsigned int reg, unsigned long *base,
598     			  unsigned long *size, mtrr_type *type)
599     {
600         unsigned long low, high;
601     
602         rdmsr (MSR_K6_UWCCR, low, high);
603         /*  Upper dword is region 1, lower is region 0  */
604         if (reg == 1) low = high;
605         /*  The base masks off on the right alignment  */
606         *base = (low & 0xFFFE0000) >> PAGE_SHIFT;
607         *type = 0;
608         if (low & 1) *type = MTRR_TYPE_UNCACHABLE;
609         if (low & 2) *type = MTRR_TYPE_WRCOMB;
610         if ( !(low & 3) )
611         {
612     	*size = 0;
613     	return;
614         }
615         /*
616          *	This needs a little explaining. The size is stored as an
617          *	inverted mask of bits of 128K granularity 15 bits long offset
618          *	2 bits
619          *
620          *	So to get a size we do invert the mask and add 1 to the lowest
621          *	mask bit (4 as its 2 bits in). This gives us a size we then shift
622          *	to turn into 128K blocks
623          *
624          *	eg		111 1111 1111 1100      is 512K
625          *
626          *	invert		000 0000 0000 0011
627          *	+1		000 0000 0000 0100
628          *	*128K	...
629          */
630         low = (~low) & 0x1FFFC;
631         *size = (low + 4) << (15 - PAGE_SHIFT);
632         return;
633     }   /*  End Function amd_get_mtrr  */
634     
635     static struct
636     {
637         unsigned long high;
638         unsigned long low;
639     } centaur_mcr[8];
640     
641     static u8 centaur_mcr_reserved;
642     static u8 centaur_mcr_type;		/* 0 for winchip, 1 for winchip2 */
643     
644     /*
645      *	Report boot time MCR setups 
646      */
647      
648     void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
649     {
650     	centaur_mcr[mcr].low = lo;
651     	centaur_mcr[mcr].high = hi;
652     }
653     
654     static void centaur_get_mcr (unsigned int reg, unsigned long *base,
655     			     unsigned long *size, mtrr_type *type)
656     {
657         *base = centaur_mcr[reg].high >> PAGE_SHIFT;
658         *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
659         *type = MTRR_TYPE_WRCOMB;	/*  If it is there, it is write-combining  */
660         if(centaur_mcr_type==1 && ((centaur_mcr[reg].low&31)&2))
661         	*type = MTRR_TYPE_UNCACHABLE;
662         if(centaur_mcr_type==1 && (centaur_mcr[reg].low&31)==25)
663         	*type = MTRR_TYPE_WRBACK;
664         if(centaur_mcr_type==0 && (centaur_mcr[reg].low&31)==31)
665         	*type = MTRR_TYPE_WRBACK;
666         
667     }   /*  End Function centaur_get_mcr  */
668     
669     static void (*get_mtrr) (unsigned int reg, unsigned long *base,
670     			 unsigned long *size, mtrr_type *type);
671     
672     static void intel_set_mtrr_up (unsigned int reg, unsigned long base,
673     			       unsigned long size, mtrr_type type, int do_safe)
674     /*  [SUMMARY] Set variable MTRR register on the local CPU.
675         <reg> The register to set.
676         <base> The base address of the region.
677         <size> The size of the region. If this is 0 the region is disabled.
678         <type> The type of the region.
679         <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
680         be done externally.
681         [RETURNS] Nothing.
682     */
683     {
684         struct set_mtrr_context ctxt;
685     
686         if (do_safe) set_mtrr_prepare (&ctxt);
687         if (size == 0)
688         {
689     	/* The invalid bit is kept in the mask, so we simply clear the
690     	   relevant mask register to disable a range. */
691     	wrmsr (MTRRphysMask_MSR (reg), 0, 0);
692         }
693         else
694         {
695     	wrmsr (MTRRphysBase_MSR (reg), base << PAGE_SHIFT | type,
696     		(base & size_and_mask) >> (32 - PAGE_SHIFT));
697     	wrmsr (MTRRphysMask_MSR (reg), -size << PAGE_SHIFT | 0x800,
698     		(-size & size_and_mask) >> (32 - PAGE_SHIFT));
699         }
700         if (do_safe) set_mtrr_done (&ctxt);
701     }   /*  End Function intel_set_mtrr_up  */
702     
703     static void cyrix_set_arr_up (unsigned int reg, unsigned long base,
704     			      unsigned long size, mtrr_type type, int do_safe)
705     {
706         struct set_mtrr_context ctxt;
707         unsigned char arr, arr_type, arr_size;
708     
709         arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
710     
711         /* count down from 32M (ARR0-ARR6) or from 2G (ARR7) */
712         if (reg >= 7)
713     	size >>= 6;
714     
715         size &= 0x7fff; /* make sure arr_size <= 14 */
716         for(arr_size = 0; size; arr_size++, size >>= 1);
717     
718         if (reg<7)
719         {
720     	switch (type) {
721     	  case MTRR_TYPE_UNCACHABLE:	arr_type =  1; break;
722     	  case MTRR_TYPE_WRCOMB:		arr_type =  9; break;
723     	  case MTRR_TYPE_WRTHROUGH:	arr_type = 24; break;
724     	  default:			arr_type =  8; break;
725     	}
726         }
727         else
728         {
729     	switch (type)
730     	{
731     	  case MTRR_TYPE_UNCACHABLE:	arr_type =  0; break;
732     	  case MTRR_TYPE_WRCOMB:		arr_type =  8; break;
733     	  case MTRR_TYPE_WRTHROUGH:	arr_type = 25; break;
734     	  default:			arr_type =  9; break;
735     	}
736         }
737     
738         if (do_safe) set_mtrr_prepare (&ctxt);
739         base <<= PAGE_SHIFT;
740         setCx86(arr,    ((unsigned char *) &base)[3]);
741         setCx86(arr+1,  ((unsigned char *) &base)[2]);
742         setCx86(arr+2, (((unsigned char *) &base)[1]) | arr_size);
743         setCx86(CX86_RCR_BASE + reg, arr_type);
744         if (do_safe) set_mtrr_done (&ctxt);
745     }   /*  End Function cyrix_set_arr_up  */
746     
747     static void amd_set_mtrr_up (unsigned int reg, unsigned long base,
748     			     unsigned long size, mtrr_type type, int do_safe)
749     /*  [SUMMARY] Set variable MTRR register on the local CPU.
750         <reg> The register to set.
751         <base> The base address of the region.
752         <size> The size of the region. If this is 0 the region is disabled.
753         <type> The type of the region.
754         <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
755         be done externally.
756         [RETURNS] Nothing.
757     */
758     {
759         u32 regs[2];
760         struct set_mtrr_context ctxt;
761     
762         if (do_safe) set_mtrr_prepare (&ctxt);
763         /*
764          *	Low is MTRR0 , High MTRR 1
765          */
766         rdmsr (MSR_K6_UWCCR, regs[0], regs[1]);
767         /*
768          *	Blank to disable
769          */
770         if (size == 0)
771     	regs[reg] = 0;
772         else
773     	/* Set the register to the base, the type (off by one) and an
774     	   inverted bitmask of the size The size is the only odd
775     	   bit. We are fed say 512K We invert this and we get 111 1111
776     	   1111 1011 but if you subtract one and invert you get the   
777     	   desired 111 1111 1111 1100 mask
778     
779     	   But ~(x - 1) == ~x + 1 == -x. Two's complement rocks!  */
780     	regs[reg] = (-size>>(15-PAGE_SHIFT) & 0x0001FFFC)
781     				| (base<<PAGE_SHIFT) | (type+1);
782     
783         /*
784          *	The writeback rule is quite specific. See the manual. Its
785          *	disable local interrupts, write back the cache, set the mtrr
786          */
787     	wbinvd();
788     	wrmsr (MSR_K6_UWCCR, regs[0], regs[1]);
789         if (do_safe) set_mtrr_done (&ctxt);
790     }   /*  End Function amd_set_mtrr_up  */
791     
792     
793     static void centaur_set_mcr_up (unsigned int reg, unsigned long base,
794     				unsigned long size, mtrr_type type,
795     				int do_safe)
796     {
797         struct set_mtrr_context ctxt;
798         unsigned long low, high;
799     
800         if (do_safe) set_mtrr_prepare( &ctxt );
801         if (size == 0)
802         {
803             /*  Disable  */
804             high = low = 0;
805         }
806         else
807         {
808     	high = base << PAGE_SHIFT;
809     	if(centaur_mcr_type == 0)
810     		low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */
811     	else
812     	{
813     		if(type == MTRR_TYPE_UNCACHABLE)
814     			low = -size << PAGE_SHIFT | 0x02;	/* NC */
815     		else
816     			low = -size << PAGE_SHIFT | 0x09;	/* WWO,WC */
817     	}
818         }
819         centaur_mcr[reg].high = high;
820         centaur_mcr[reg].low = low;
821         wrmsr (MSR_IDT_MCR0 + reg, low, high);
822         if (do_safe) set_mtrr_done( &ctxt );
823     }   /*  End Function centaur_set_mtrr_up  */
824     
825     static void (*set_mtrr_up) (unsigned int reg, unsigned long base,
826     			    unsigned long size, mtrr_type type,
827     			    int do_safe);
828     
829     #ifdef CONFIG_SMP
830     
831     struct mtrr_var_range
832     {
833         unsigned long base_lo;
834         unsigned long base_hi;
835         unsigned long mask_lo;
836         unsigned long mask_hi;
837     };
838     
839     
840     /*  Get the MSR pair relating to a var range  */
841     static void __init get_mtrr_var_range (unsigned int index,
842     					   struct mtrr_var_range *vr)
843     {
844         rdmsr (MTRRphysBase_MSR (index), vr->base_lo, vr->base_hi);
845         rdmsr (MTRRphysMask_MSR (index), vr->mask_lo, vr->mask_hi);
846     }   /*  End Function get_mtrr_var_range  */
847     
848     
849     /*  Set the MSR pair relating to a var range. Returns TRUE if
850         changes are made  */
851     static int __init set_mtrr_var_range_testing (unsigned int index,
852     						  struct mtrr_var_range *vr)
853     {
854         unsigned int lo, hi;
855         int changed = FALSE;
856     
857         rdmsr(MTRRphysBase_MSR(index), lo, hi);
858         if ( (vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
859     	 || (vr->base_hi & 0xfUL) != (hi & 0xfUL) )
860         {
861     	wrmsr (MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
862     	changed = TRUE;
863         }
864     
865         rdmsr (MTRRphysMask_MSR(index), lo, hi);
866     
867         if ( (vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
868     	 || (vr->mask_hi & 0xfUL) != (hi & 0xfUL) )
869         {
870     	wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
871     	changed = TRUE;
872         }
873         return changed;
874     }   /*  End Function set_mtrr_var_range_testing  */
875     
876     static void __init get_fixed_ranges(mtrr_type *frs)
877     {
878         unsigned long *p = (unsigned long *)frs;
879         int i;
880     
881         rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
882     
883         for (i = 0; i < 2; i++)
884     	rdmsr(MTRRfix16K_80000_MSR + i, p[2 + i*2], p[3 + i*2]);
885         for (i = 0; i < 8; i++)
886     	rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i*2], p[7 + i*2]);
887     }   /*  End Function get_fixed_ranges  */
888     
889     static int __init set_fixed_ranges_testing(mtrr_type *frs)
890     {
891         unsigned long *p = (unsigned long *)frs;
892         int changed = FALSE;
893         int i;
894         unsigned long lo, hi;
895     
896         rdmsr(MTRRfix64K_00000_MSR, lo, hi);
897         if (p[0] != lo || p[1] != hi)
898         {
899     	wrmsr (MTRRfix64K_00000_MSR, p[0], p[1]);
900     	changed = TRUE;
901         }
902     
903         for (i = 0; i < 2; i++)
904         {
905     	rdmsr (MTRRfix16K_80000_MSR + i, lo, hi);
906     	if (p[2 + i*2] != lo || p[3 + i*2] != hi)
907     	{
908     	    wrmsr (MTRRfix16K_80000_MSR + i, p[2 + i*2], p[3 + i*2]);
909     	    changed = TRUE;
910     	}
911         }
912     
913         for (i = 0; i < 8; i++)
914         {
915     	rdmsr (MTRRfix4K_C0000_MSR + i, lo, hi);
916     	if (p[6 + i*2] != lo || p[7 + i*2] != hi)
917     	{
918     	    wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i*2], p[7 + i*2]);
919     	    changed = TRUE;
920     	}
921         }
922         return changed;
923     }   /*  End Function set_fixed_ranges_testing  */
924     
925     struct mtrr_state
926     {
927         unsigned int num_var_ranges;
928         struct mtrr_var_range *var_ranges;
929         mtrr_type fixed_ranges[NUM_FIXED_RANGES];
930         unsigned char enabled;
931         mtrr_type def_type;
932     };
933     
934     
935     /*  Grab all of the MTRR state for this CPU into *state  */
936     static void __init get_mtrr_state(struct mtrr_state *state)
937     {
938         unsigned int nvrs, i;
939         struct mtrr_var_range *vrs;
940         unsigned long lo, dummy;
941     
942         nvrs = state->num_var_ranges = get_num_var_ranges();
943         vrs = state->var_ranges
944                   = kmalloc (nvrs * sizeof (struct mtrr_var_range), GFP_KERNEL);
945         if (vrs == NULL)
946     	nvrs = state->num_var_ranges = 0;
947     
948         for (i = 0; i < nvrs; i++)
949     	get_mtrr_var_range (i, &vrs[i]);
950         get_fixed_ranges (state->fixed_ranges);
951     
952         rdmsr (MTRRdefType_MSR, lo, dummy);
953         state->def_type = (lo & 0xff);
954         state->enabled = (lo & 0xc00) >> 10;
955     }   /*  End Function get_mtrr_state  */
956     
957     
958     /*  Free resources associated with a struct mtrr_state  */
959     static void __init finalize_mtrr_state(struct mtrr_state *state)
960     {
961         if (state->var_ranges) kfree (state->var_ranges);
962     }   /*  End Function finalize_mtrr_state  */
963     
964     
965     static unsigned long __init set_mtrr_state (struct mtrr_state *state,
966     						struct set_mtrr_context *ctxt)
967     /*  [SUMMARY] Set the MTRR state for this CPU.
968         <state> The MTRR state information to read.
969         <ctxt> Some relevant CPU context.
970         [NOTE] The CPU must already be in a safe state for MTRR changes.
971         [RETURNS] 0 if no changes made, else a mask indication what was changed.
972     */
973     {
974         unsigned int i;
975         unsigned long change_mask = 0;
976     
977         for (i = 0; i < state->num_var_ranges; i++)
978     	if ( set_mtrr_var_range_testing (i, &state->var_ranges[i]) )
979     	    change_mask |= MTRR_CHANGE_MASK_VARIABLE;
980     
981         if ( set_fixed_ranges_testing(state->fixed_ranges) )
982     	change_mask |= MTRR_CHANGE_MASK_FIXED;
983         /*  Set_mtrr_restore restores the old value of MTRRdefType,
984     	so to set it we fiddle with the saved value  */
985         if ( (ctxt->deftype_lo & 0xff) != state->def_type
986     	 || ( (ctxt->deftype_lo & 0xc00) >> 10 ) != state->enabled)
987         {
988     	ctxt->deftype_lo |= (state->def_type | state->enabled << 10);
989     	change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
990         }
991     
992         return change_mask;
993     }   /*  End Function set_mtrr_state  */
994     
995     
996     static atomic_t undone_count;
997     static volatile int wait_barrier_execute = FALSE;
998     static volatile int wait_barrier_cache_enable = FALSE;
999     
1000     struct set_mtrr_data
1001     {
1002         unsigned long smp_base;
1003         unsigned long smp_size;
1004         unsigned int smp_reg;
1005         mtrr_type smp_type;
1006     };
1007     
1008     static void ipi_handler (void *info)
1009     /*  [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
1010         [RETURNS] Nothing.
1011     */
1012     {
1013         struct set_mtrr_data *data = info;
1014         struct set_mtrr_context ctxt;
1015     
1016         set_mtrr_prepare (&ctxt);
1017         /*  Notify master that I've flushed and disabled my cache  */
1018         atomic_dec (&undone_count);
1019         while (wait_barrier_execute) barrier ();
1020         /*  The master has cleared me to execute  */
1021         (*set_mtrr_up) (data->smp_reg, data->smp_base, data->smp_size,
1022     		    data->smp_type, FALSE);
1023         /*  Notify master CPU that I've executed the function  */
1024         atomic_dec (&undone_count);
1025         /*  Wait for master to clear me to enable cache and return  */
1026         while (wait_barrier_cache_enable) barrier ();
1027         set_mtrr_done (&ctxt);
1028     }   /*  End Function ipi_handler  */
1029     
1030     static void set_mtrr_smp (unsigned int reg, unsigned long base,
1031     			  unsigned long size, mtrr_type type)
1032     {
1033         struct set_mtrr_data data;
1034         struct set_mtrr_context ctxt;
1035     
1036         data.smp_reg = reg;
1037         data.smp_base = base;
1038         data.smp_size = size;
1039         data.smp_type = type;
1040         wait_barrier_execute = TRUE;
1041         wait_barrier_cache_enable = TRUE;
1042         atomic_set (&undone_count, smp_num_cpus - 1);
1043         /*  Start the ball rolling on other CPUs  */
1044         if (smp_call_function (ipi_handler, &data, 1, 0) != 0)
1045     	panic ("mtrr: timed out waiting for other CPUs\n");
1046         /* Flush and disable the local CPU's cache */
1047         set_mtrr_prepare (&ctxt);
1048         /*  Wait for all other CPUs to flush and disable their caches  */
1049         while (atomic_read (&undone_count) > 0) barrier ();
1050         /* Set up for completion wait and then release other CPUs to change MTRRs*/
1051         atomic_set (&undone_count, smp_num_cpus - 1);
1052         wait_barrier_execute = FALSE;
1053         (*set_mtrr_up) (reg, base, size, type, FALSE);
1054         /*  Now wait for other CPUs to complete the function  */
1055         while (atomic_read (&undone_count) > 0) barrier ();
1056         /*  Now all CPUs should have finished the function. Release the barrier to
1057     	allow them to re-enable their caches and return from their interrupt,
1058     	then enable the local cache and return  */
1059         wait_barrier_cache_enable = FALSE;
1060         set_mtrr_done (&ctxt);
1061     }   /*  End Function set_mtrr_smp  */
1062     
1063     
1064     /*  Some BIOS's are fucked and don't set all MTRRs the same!  */
1065     static void __init mtrr_state_warn(unsigned long mask)
1066     {
1067         if (!mask) return;
1068         if (mask & MTRR_CHANGE_MASK_FIXED)
1069     	printk ("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
1070         if (mask & MTRR_CHANGE_MASK_VARIABLE)
1071     	printk ("mtrr: your CPUs had inconsistent variable MTRR settings\n");
1072         if (mask & MTRR_CHANGE_MASK_DEFTYPE)
1073     	printk ("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
1074         printk ("mtrr: probably your BIOS does not setup all CPUs\n");
1075     }   /*  End Function mtrr_state_warn  */
1076     
1077     #endif  /*  CONFIG_SMP  */
1078     
1079     static char *attrib_to_str (int x)
1080     {
1081         return (x <= 6) ? mtrr_strings[x] : "?";
1082     }   /*  End Function attrib_to_str  */
1083     
1084     static void init_table (void)
1085     {
1086         int i, max;
1087     
1088         max = get_num_var_ranges ();
1089         if ( ( usage_table = kmalloc (max * sizeof *usage_table, GFP_KERNEL) )
1090     	 == NULL )
1091         {
1092     	printk ("mtrr: could not allocate\n");
1093     	return;
1094         }
1095         for (i = 0; i < max; i++) usage_table[i] = 1;
1096     #ifdef USERSPACE_INTERFACE
1097         if ( ( ascii_buffer = kmalloc (max * LINE_SIZE, GFP_KERNEL) ) == NULL )
1098         {
1099     	printk ("mtrr: could not allocate\n");
1100     	return;
1101         }
1102         ascii_buf_bytes = 0;
1103         compute_ascii ();
1104     #endif
1105     }   /*  End Function init_table  */
1106     
1107     static int generic_get_free_region (unsigned long base, unsigned long size)
1108     /*  [SUMMARY] Get a free MTRR.
1109         <base> The starting (base) address of the region.
1110         <size> The size (in bytes) of the region.
1111         [RETURNS] The index of the region on success, else -1 on error.
1112     */
1113     {
1114         int i, max;
1115         mtrr_type ltype;
1116         unsigned long lbase, lsize;
1117     
1118         max = get_num_var_ranges ();
1119         for (i = 0; i < max; ++i)
1120         {
1121     	(*get_mtrr) (i, &lbase, &lsize, &ltype);
1122     	if (lsize == 0) return i;
1123         }
1124         return -ENOSPC;
1125     }   /*  End Function generic_get_free_region  */
1126     
1127     static int centaur_get_free_region (unsigned long base, unsigned long size)
1128     /*  [SUMMARY] Get a free MTRR.
1129         <base> The starting (base) address of the region.
1130         <size> The size (in bytes) of the region.
1131         [RETURNS] The index of the region on success, else -1 on error.
1132     */
1133     {
1134         int i, max;
1135         mtrr_type ltype;
1136         unsigned long lbase, lsize;
1137     
1138         max = get_num_var_ranges ();
1139         for (i = 0; i < max; ++i)
1140         {
1141         	if(centaur_mcr_reserved & (1<<i))
1142         		continue;
1143     	(*get_mtrr) (i, &lbase, &lsize, &ltype);
1144     	if (lsize == 0) return i;
1145         }
1146         return -ENOSPC;
1147     }   /*  End Function generic_get_free_region  */
1148     
1149     static int cyrix_get_free_region (unsigned long base, unsigned long size)
1150     /*  [SUMMARY] Get a free ARR.
1151         <base> The starting (base) address of the region.
1152         <size> The size (in bytes) of the region.
1153         [RETURNS] The index of the region on success, else -1 on error.
1154     */
1155     {
1156         int i;
1157         mtrr_type ltype;
1158         unsigned long lbase, lsize;
1159     
1160         /* If we are to set up a region >32M then look at ARR7 immediately */
1161         if (size > 0x2000)
1162         {
1163     	cyrix_get_arr (7, &lbase, &lsize, &ltype);
1164     	if (lsize == 0) return 7;
1165     	/*  Else try ARR0-ARR6 first  */
1166         }
1167         else
1168         {
1169     	for (i = 0; i < 7; i++)
1170     	{
1171     	    cyrix_get_arr (i, &lbase, &lsize, &ltype);
1172     	    if ((i == 3) && arr3_protected) continue;
1173     	    if (lsize == 0) return i;
1174     	}
1175     	/* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */
1176     	cyrix_get_arr (i, &lbase, &lsize, &ltype);
1177     	if ((lsize == 0) && (size >= 0x40)) return i;
1178         }
1179         return -ENOSPC;
1180     }   /*  End Function cyrix_get_free_region  */
1181     
1182     static int (*get_free_region) (unsigned long base,
1183     			       unsigned long size) = generic_get_free_region;
1184     
1185     /**
1186      *	mtrr_add_page - Add a memory type region
1187      *	@base: Physical base address of region in pages (4 KB)
1188      *	@size: Physical size of region in pages (4 KB)
1189      *	@type: Type of MTRR desired
1190      *	@increment: If this is true do usage counting on the region
1191      *
1192      *	Memory type region registers control the caching on newer Intel and
1193      *	non Intel processors. This function allows drivers to request an
1194      *	MTRR is added. The details and hardware specifics of each processor's
1195      *	implementation are hidden from the caller, but nevertheless the 
1196      *	caller should expect to need to provide a power of two size on an
1197      *	equivalent power of two boundary.
1198      *
1199      *	If the region cannot be added either because all regions are in use
1200      *	or the CPU cannot support it a negative value is returned. On success
1201      *	the register number for this entry is returned, but should be treated
1202      *	as a cookie only.
1203      *
1204      *	On a multiprocessor machine the changes are made to all processors.
1205      *	This is required on x86 by the Intel processors.
1206      *
1207      *	The available types are
1208      *
1209      *	%MTRR_TYPE_UNCACHABLE	-	No caching
1210      *
1211      *	%MTRR_TYPE_WRBACK	-	Write data back in bursts whenever
1212      *
1213      *	%MTRR_TYPE_WRCOMB	-	Write data back soon but allow bursts
1214      *
1215      *	%MTRR_TYPE_WRTHROUGH	-	Cache reads but not writes
1216      *
1217      *	BUGS: Needs a quiet flag for the cases where drivers do not mind
1218      *	failures and do not wish system log messages to be sent.
1219      */
1220     
1221     int mtrr_add_page(unsigned long base, unsigned long size, unsigned int type, char increment)
1222     {
1223     /*  [SUMMARY] Add an MTRR entry.
1224         <base> The starting (base, in pages) address of the region.
1225         <size> The size of the region. (in pages)
1226         <type> The type of the new region.
1227         <increment> If true and the region already exists, the usage count will be
1228         incremented.
1229         [RETURNS] The MTRR register on success, else a negative number indicating
1230         the error code.
1231         [NOTE] This routine uses a spinlock.
1232     */
1233         int i, max;
1234         mtrr_type ltype;
1235         unsigned long lbase, lsize, last;
1236     
1237         switch ( mtrr_if )
1238         {
1239         case MTRR_IF_NONE:
1240     	return -ENXIO;		/* No MTRRs whatsoever */
1241     
1242         case MTRR_IF_AMD_K6:
1243     	/* Apply the K6 block alignment and size rules
1244     	   In order
1245     	   o Uncached or gathering only
1246     	   o 128K or bigger block
1247     	   o Power of 2 block
1248     	   o base suitably aligned to the power
1249     	*/
1250     	if ( type > MTRR_TYPE_WRCOMB || size < (1 << (17-PAGE_SHIFT)) ||
1251     	     (size & ~(size-1))-size || ( base & (size-1) ) )
1252     	    return -EINVAL;
1253     	break;
1254     
1255         case MTRR_IF_INTEL:
1256     	/*  For Intel PPro stepping <= 7, must be 4 MiB aligned  */
1257     	if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
1258     	     boot_cpu_data.x86 == 6 &&
1259     	     boot_cpu_data.x86_model == 1 &&
1260     	     boot_cpu_data.x86_mask <= 7 )
1261     	{
1262     	    if ( base & ((1 << (22-PAGE_SHIFT))-1) )
1263     	    {
1264     		printk (KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
1265     		return -EINVAL;
1266     	    }
1267     	}
1268     	/* Fall through */
1269     	
1270         case MTRR_IF_CYRIX_ARR:
1271         case MTRR_IF_CENTAUR_MCR:
1272             if ( mtrr_if == MTRR_IF_CENTAUR_MCR )
1273     	{
1274     	    /*
1275     	     *	FIXME: Winchip2 supports uncached
1276     	     */
1277     	    if (type != MTRR_TYPE_WRCOMB && (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE))
1278     	    {
1279     		printk (KERN_WARNING "mtrr: only write-combining%s supported\n",
1280     			centaur_mcr_type?" and uncacheable are":" is");
1281     		return -EINVAL;
1282     	    }
1283     	}
1284     	else if (base + size < 0x100)
1285     	{
1286     	    printk (KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n",
1287     		    base, size);
1288     	    return -EINVAL;
1289     	}
1290     	/*  Check upper bits of base and last are equal and lower bits are 0
1291     	    for base and 1 for last  */
1292     	last = base + size - 1;
1293     	for (lbase = base; !(lbase & 1) && (last & 1);
1294     	     lbase = lbase >> 1, last = last >> 1);
1295     	if (lbase != last)
1296     	{
1297     	    printk (KERN_WARNING "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
1298     		    base, size);
1299     	    return -EINVAL;
1300     	}
1301     	break;
1302     
1303         default:
1304     	return -EINVAL;
1305         }
1306     
1307         if (type >= MTRR_NUM_TYPES)
1308         {
1309     	printk ("mtrr: type: %u illegal\n", type);
1310     	return -EINVAL;
1311         }
1312     
1313         /*  If the type is WC, check that this processor supports it  */
1314         if ( (type == MTRR_TYPE_WRCOMB) && !have_wrcomb () )
1315         {
1316             printk (KERN_WARNING "mtrr: your processor doesn't support write-combining\n");
1317             return -ENOSYS;
1318         }
1319     
1320         if ( base & size_or_mask || size  & size_or_mask )
1321         {
1322     	printk ("mtrr: base or size exceeds the MTRR width\n");
1323     	return -EINVAL;
1324         }
1325     
1326         increment = increment ? 1 : 0;
1327         max = get_num_var_ranges ();
1328         /*  Search for existing MTRR  */
1329         down(&main_lock);
1330         for (i = 0; i < max; ++i)
1331         {
1332     	(*get_mtrr) (i, &lbase, &lsize, &ltype);
1333     	if (base >= lbase + lsize) continue;
1334     	if ( (base < lbase) && (base + size <= lbase) ) continue;
1335     	/*  At this point we know there is some kind of overlap/enclosure  */
1336     	if ( (base < lbase) || (base + size > lbase + lsize) )
1337     	{
1338     	    up(&main_lock);
1339     	    printk (KERN_WARNING "mtrr: 0x%lx000,0x%lx000 overlaps existing"
1340     		    " 0x%lx000,0x%lx000\n",
1341     		    base, size, lbase, lsize);
1342     	    return -EINVAL;
1343     	}
1344     	/*  New region is enclosed by an existing region  */
1345     	if (ltype != type)
1346     	{
1347     	    if (type == MTRR_TYPE_UNCACHABLE) continue;
1348     	    up(&main_lock);
1349     	    printk ( "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
1350     		     base, size, attrib_to_str (ltype), attrib_to_str (type) );
1351     	    return -EINVAL;
1352     	}
1353     	if (increment) ++usage_table[i];
1354     	compute_ascii ();
1355     	up(&main_lock);
1356     	return i;
1357         }
1358         /*  Search for an empty MTRR  */
1359         i = (*get_free_region) (base, size);
1360         if (i < 0)
1361         {
1362     	up(&main_lock);
1363     	printk ("mtrr: no more MTRRs available\n");
1364     	return i;
1365         }
1366         set_mtrr (i, base, size, type);
1367         usage_table[i] = 1;
1368         compute_ascii ();
1369         up(&main_lock);
1370         return i;
1371     }   /*  End Function mtrr_add_page  */
1372     
1373     /**
1374      *	mtrr_add - Add a memory type region
1375      *	@base: Physical base address of region
1376      *	@size: Physical size of region
1377      *	@type: Type of MTRR desired
1378      *	@increment: If this is true do usage counting on the region
1379      *
1380      *	Memory type region registers control the caching on newer Intel and
1381      *	non Intel processors. This function allows drivers to request an
1382      *	MTRR is added. The details and hardware specifics of each processor's
1383      *	implementation are hidden from the caller, but nevertheless the 
1384      *	caller should expect to need to provide a power of two size on an
1385      *	equivalent power of two boundary.
1386      *
1387      *	If the region cannot be added either because all regions are in use
1388      *	or the CPU cannot support it a negative value is returned. On success
1389      *	the register number for this entry is returned, but should be treated
1390      *	as a cookie only.
1391      *
1392      *	On a multiprocessor machine the changes are made to all processors.
1393      *	This is required on x86 by the Intel processors.
1394      *
1395      *	The available types are
1396      *
1397      *	%MTRR_TYPE_UNCACHABLE	-	No caching
1398      *
1399      *	%MTRR_TYPE_WRBACK	-	Write data back in bursts whenever
1400      *
1401      *	%MTRR_TYPE_WRCOMB	-	Write data back soon but allow bursts
1402      *
1403      *	%MTRR_TYPE_WRTHROUGH	-	Cache reads but not writes
1404      *
1405      *	BUGS: Needs a quiet flag for the cases where drivers do not mind
1406      *	failures and do not wish system log messages to be sent.
1407      */
1408     
1409     int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char increment)
1410     {
1411     /*  [SUMMARY] Add an MTRR entry.
1412         <base> The starting (base) address of the region.
1413         <size> The size (in bytes) of the region.
1414         <type> The type of the new region.
1415         <increment> If true and the region already exists, the usage count will be
1416         incremented.
1417         [RETURNS] The MTRR register on success, else a negative number indicating
1418         the error code.
1419     */
1420     
1421         if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1422         {
1423     	printk ("mtrr: size and base must be multiples of 4 kiB\n");
1424     	printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1425     	return -EINVAL;
1426         }
1427         return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, increment);
1428     }   /*  End Function mtrr_add  */
1429     
1430     /**
1431      *	mtrr_del_page - delete a memory type region
1432      *	@reg: Register returned by mtrr_add
1433      *	@base: Physical base address
1434      *	@size: Size of region
1435      *
1436      *	If register is supplied then base and size are ignored. This is
1437      *	how drivers should call it.
1438      *
1439      *	Releases an MTRR region. If the usage count drops to zero the 
1440      *	register is freed and the region returns to default state.
1441      *	On success the register is returned, on failure a negative error
1442      *	code.
1443      */
1444      
1445     int mtrr_del_page (int reg, unsigned long base, unsigned long size)
1446     /*  [SUMMARY] Delete MTRR/decrement usage count.
1447         <reg> The register. If this is less than 0 then <<base>> and <<size>> must
1448         be supplied.
1449         <base> The base address of the region. This is ignored if <<reg>> is >= 0.
1450         <size> The size of the region. This is ignored if <<reg>> is >= 0.
1451         [RETURNS] The register on success, else a negative number indicating
1452         the error code.
1453         [NOTE] This routine uses a spinlock.
1454     */
1455     {
1456         int i, max;
1457         mtrr_type ltype;
1458         unsigned long lbase, lsize;
1459     
1460         if ( mtrr_if == MTRR_IF_NONE ) return -ENXIO;
1461     
1462         max = get_num_var_ranges ();
1463         down (&main_lock);
1464         if (reg < 0)
1465         {
1466     	/*  Search for existing MTRR  */
1467     	for (i = 0; i < max; ++i)
1468     	{
1469     	    (*get_mtrr) (i, &lbase, &lsize, &ltype);
1470     	    if (lbase == base && lsize == size)
1471     	    {
1472     		reg = i;
1473     		break;
1474     	    }
1475     	}
1476     	if (reg < 0)
1477     	{
1478     	    up(&main_lock);
1479     	    printk ("mtrr: no MTRR for %lx000,%lx000 found\n", base, size);
1480     	    return -EINVAL;
1481     	}
1482         }
1483         if (reg >= max)
1484         {
1485     	up (&main_lock);
1486     	printk ("mtrr: register: %d too big\n", reg);
1487     	return -EINVAL;
1488         }
1489         if ( mtrr_if == MTRR_IF_CYRIX_ARR )
1490         {
1491     	if ( (reg == 3) && arr3_protected )
1492     	{
1493     	    up (&main_lock);
1494     	    printk ("mtrr: ARR3 cannot be changed\n");
1495     	    return -EINVAL;
1496     	}
1497         }
1498         (*get_mtrr) (reg, &lbase, &lsize, &ltype);
1499         if (lsize < 1)
1500         {
1501     	up (&main_lock);
1502     	printk ("mtrr: MTRR %d not used\n", reg);
1503     	return -EINVAL;
1504         }
1505         if (usage_table[reg] < 1)
1506         {
1507     	up (&main_lock);
1508     	printk ("mtrr: reg: %d has count=0\n", reg);
1509     	return -EINVAL;
1510         }
1511         if (--usage_table[reg] < 1) set_mtrr (reg, 0, 0, 0);
1512         compute_ascii ();
1513         up (&main_lock);
1514         return reg;
1515     }   /*  End Function mtrr_del_page  */
1516     
1517     /**
1518      *	mtrr_del - delete a memory type region
1519      *	@reg: Register returned by mtrr_add
1520      *	@base: Physical base address
1521      *	@size: Size of region
1522      *
1523      *	If register is supplied then base and size are ignored. This is
1524      *	how drivers should call it.
1525      *
1526      *	Releases an MTRR region. If the usage count drops to zero the 
1527      *	register is freed and the region returns to default state.
1528      *	On success the register is returned, on failure a negative error
1529      *	code.
1530      */
1531      
1532     int mtrr_del (int reg, unsigned long base, unsigned long size)
1533     /*  [SUMMARY] Delete MTRR/decrement usage count.
1534         <reg> The register. If this is less than 0 then <<base>> and <<size>> must
1535         be supplied.
1536         <base> The base address of the region. This is ignored if <<reg>> is >= 0.
1537         <size> The size of the region. This is ignored if <<reg>> is >= 0.
1538         [RETURNS] The register on success, else a negative number indicating
1539         the error code.
1540     */
1541     {
1542         if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1543         {
1544     	printk ("mtrr: size and base must be multiples of 4 kiB\n");
1545     	printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1546     	return -EINVAL;
1547         }
1548         return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
1549     }
1550     
1551     #ifdef USERSPACE_INTERFACE
1552     
1553     static int mtrr_file_add (unsigned long base, unsigned long size,
1554     			  unsigned int type, char increment, struct file *file, int page)
1555     {
1556         int reg, max;
1557         unsigned int *fcount = file->private_data;
1558     
1559         max = get_num_var_ranges ();
1560         if (fcount == NULL)
1561         {
1562     	if ( ( fcount = kmalloc (max * sizeof *fcount, GFP_KERNEL) ) == NULL )
1563     	{
1564     	    printk ("mtrr: could not allocate\n");
1565     	    return -ENOMEM;
1566     	}
1567     	memset (fcount, 0, max * sizeof *fcount);
1568     	file->private_data = fcount;
1569         }
1570         if (!page) {
1571     	if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1572     	{
1573     	    printk ("mtrr: size and base must be multiples of 4 kiB\n");
1574     	    printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1575     	    return -EINVAL;
1576     	}
1577     	base >>= PAGE_SHIFT;
1578     	size >>= PAGE_SHIFT;
1579         }
1580         reg = mtrr_add_page (base, size, type, 1);
1581         if (reg >= 0) ++fcount[reg];
1582         return reg;
1583     }   /*  End Function mtrr_file_add  */
1584     
1585     static int mtrr_file_del (unsigned long base, unsigned long size,
1586     			  struct file *file, int page)
1587     {
1588         int reg;
1589         unsigned int *fcount = file->private_data;
1590     
1591         if (!page) {
1592     	if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1593     	{
1594     	    printk ("mtrr: size and base must be multiples of 4 kiB\n");
1595     	    printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1596     	    return -EINVAL;
1597     	}
1598     	base >>= PAGE_SHIFT;
1599     	size >>= PAGE_SHIFT;
1600         }
1601         reg = mtrr_del_page (-1, base, size);
1602         if (reg < 0) return reg;
1603         if (fcount == NULL) return reg;
1604         if (fcount[reg] < 1) return -EINVAL;
1605         --fcount[reg];
1606         return reg;
1607     }   /*  End Function mtrr_file_del  */
1608     
1609     static ssize_t mtrr_read (struct file *file, char *buf, size_t len,
1610     			  loff_t *ppos)
1611     {
1612         if (*ppos >= ascii_buf_bytes) return 0;
1613         if (*ppos + len > ascii_buf_bytes) len = ascii_buf_bytes - *ppos;
1614         if ( copy_to_user (buf, ascii_buffer + *ppos, len) ) return -EFAULT;
1615         *ppos += len;
1616         return len;
1617     }   /*  End Function mtrr_read  */
1618     
1619     static ssize_t mtrr_write (struct file *file, const char *buf, size_t len,
1620     			   loff_t *ppos)
1621     /*  Format of control line:
1622         "base=%Lx size=%Lx type=%s"     OR:
1623         "disable=%d"
1624     */
1625     {
1626         int i, err;
1627         unsigned long reg;
1628         unsigned long long base, size;
1629         char *ptr;
1630         char line[LINE_SIZE];
1631     
1632         if ( !suser () ) return -EPERM;
1633         /*  Can't seek (pwrite) on this device  */
1634         if (ppos != &file->f_pos) return -ESPIPE;
1635         memset (line, 0, LINE_SIZE);
1636         if (len > LINE_SIZE) len = LINE_SIZE;
1637         if ( copy_from_user (line, buf, len - 1) ) return -EFAULT;
1638         ptr = line + strlen (line) - 1;
1639         if (*ptr == '\n') *ptr = '\0';
1640         if ( !strncmp (line, "disable=", 8) )
1641         {
1642     	reg = simple_strtoul (line + 8, &ptr, 0);
1643     	err = mtrr_del_page (reg, 0, 0);
1644     	if (err < 0) return err;
1645     	return len;
1646         }
1647         if ( strncmp (line, "base=", 5) )
1648         {
1649     	printk ("mtrr: no \"base=\" in line: \"%s\"\n", line);
1650     	return -EINVAL;
1651         }
1652         base = simple_strtoull (line + 5, &ptr, 0);
1653         for (; isspace (*ptr); ++ptr);
1654         if ( strncmp (ptr, "size=", 5) )
1655         {
1656     	printk ("mtrr: no \"size=\" in line: \"%s\"\n", line);
1657     	return -EINVAL;
1658         }
1659         size = simple_strtoull (ptr + 5, &ptr, 0);
1660         if ( (base & 0xfff) || (size & 0xfff) )
1661         {
1662     	printk ("mtrr: size and base must be multiples of 4 kiB\n");
1663     	printk ("mtrr: size: 0x%Lx  base: 0x%Lx\n", size, base);
1664     	return -EINVAL;
1665         }
1666         for (; isspace (*ptr); ++ptr);
1667         if ( strncmp (ptr, "type=", 5) )
1668         {
1669     	printk ("mtrr: no \"type=\" in line: \"%s\"\n", line);
1670     	return -EINVAL;
1671         }
1672         ptr += 5;
1673         for (; isspace (*ptr); ++ptr);
1674         for (i = 0; i < MTRR_NUM_TYPES; ++i)
1675         {
1676     	if ( strcmp (ptr, mtrr_strings[i]) ) continue;
1677     	base >>= PAGE_SHIFT;
1678     	size >>= PAGE_SHIFT;
1679     	err = mtrr_add_page ((unsigned long)base, (unsigned long)size, i, 1);
1680     	if (err < 0) return err;
1681     	return len;
1682         }
1683         printk ("mtrr: illegal type: \"%s\"\n", ptr);
1684         return -EINVAL;
1685     }   /*  End Function mtrr_write  */
1686     
1687     static int mtrr_ioctl (struct inode *inode, struct file *file,
1688     		       unsigned int cmd, unsigned long arg)
1689     {
1690         int err;
1691         mtrr_type type;
1692         struct mtrr_sentry sentry;
1693         struct mtrr_gentry gentry;
1694     
1695         switch (cmd)
1696         {
1697           default:
1698     	return -ENOIOCTLCMD;
1699           case MTRRIOC_ADD_ENTRY:
1700     	if ( !suser () ) return -EPERM;
1701     	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1702     	    return -EFAULT;
1703     	err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file, 0);
1704     	if (err < 0) return err;
1705     	break;
1706           case MTRRIOC_SET_ENTRY:
1707     	if ( !suser () ) return -EPERM;
1708     	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1709     	    return -EFAULT;
1710     	err = mtrr_add (sentry.base, sentry.size, sentry.type, 0);
1711     	if (err < 0) return err;
1712     	break;
1713           case MTRRIOC_DEL_ENTRY:
1714     	if ( !suser () ) return -EPERM;
1715     	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1716     	    return -EFAULT;
1717     	err = mtrr_file_del (sentry.base, sentry.size, file, 0);
1718     	if (err < 0) return err;
1719     	break;
1720           case MTRRIOC_KILL_ENTRY:
1721     	if ( !suser () ) return -EPERM;
1722     	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1723     	    return -EFAULT;
1724     	err = mtrr_del (-1, sentry.base, sentry.size);
1725     	if (err < 0) return err;
1726     	break;
1727           case MTRRIOC_GET_ENTRY:
1728     	if ( copy_from_user (&gentry, (void *) arg, sizeof gentry) )
1729     	    return -EFAULT;
1730     	if ( gentry.regnum >= get_num_var_ranges () ) return -EINVAL;
1731     	(*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
1732     
1733     	/* Hide entries that go above 4GB */
1734     	if (gentry.base + gentry.size > 0x100000 || gentry.size == 0x100000)
1735     	    gentry.base = gentry.size = gentry.type = 0;
1736     	else {
1737     	    gentry.base <<= PAGE_SHIFT;
1738     	    gentry.size <<= PAGE_SHIFT;
1739     	    gentry.type = type;
1740     	}
1741     
1742     	if ( copy_to_user ( (void *) arg, &gentry, sizeof gentry) )
1743     	     return -EFAULT;
1744     	break;
1745           case MTRRIOC_ADD_PAGE_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, 1);
1750     	if (err < 0) return err;
1751     	break;
1752           case MTRRIOC_SET_PAGE_ENTRY:
1753     	if ( !suser () ) return -EPERM;
1754     	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1755     	    return -EFAULT;
1756     	err = mtrr_add_page (sentry.base, sentry.size, sentry.type, 0);
1757     	if (err < 0) return err;
1758     	break;
1759           case MTRRIOC_DEL_PAGE_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, 1);
1764     	if (err < 0) return err;
1765     	break;
1766           case MTRRIOC_KILL_PAGE_ENTRY:
1767     	if ( !suser () ) return -EPERM;
1768     	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1769     	    return -EFAULT;
1770     	err = mtrr_del_page (-1, sentry.base, sentry.size);
1771     	if (err < 0) return err;
1772     	break;
1773           case MTRRIOC_GET_PAGE_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     	gentry.type = type;
1779     
1780     	if ( copy_to_user ( (void *) arg, &gentry, sizeof gentry) )
1781     	     return -EFAULT;
1782     	break;
1783         }
1784         return 0;
1785     }   /*  End Function mtrr_ioctl  */
1786     
1787     static int mtrr_close (struct inode *ino, struct file *file)
1788     {
1789         int i, max;
1790         unsigned int *fcount = file->private_data;
1791     
1792         if (fcount == NULL) return 0;
1793         lock_kernel();
1794         max = get_num_var_ranges ();
1795         for (i = 0; i < max; ++i)
1796         {
1797     	while (fcount[i] > 0)
1798     	{
1799     	    if (mtrr_del (i, 0, 0) < 0) printk ("mtrr: reg %d not used\n", i);
1800     	    --fcount[i];
1801     	}
1802         }
1803         unlock_kernel();
1804         kfree (fcount);
1805         file->private_data = NULL;
1806         return 0;
1807     }   /*  End Function mtrr_close  */
1808     
1809     static struct file_operations mtrr_fops =
1810     {
1811         owner:	THIS_MODULE,
1812         read:	mtrr_read,
1813         write:	mtrr_write,
1814         ioctl:	mtrr_ioctl,
1815         release:	mtrr_close,
1816     };
1817     
1818     #  ifdef CONFIG_PROC_FS
1819     
1820     static struct proc_dir_entry *proc_root_mtrr;
1821     
1822     #  endif  /*  CONFIG_PROC_FS  */
1823     
1824     static devfs_handle_t devfs_handle;
1825     
1826     static void compute_ascii (void)
1827     {
1828         char factor;
1829         int i, max;
1830         mtrr_type type;
1831         unsigned long base, size;
1832     
1833         ascii_buf_bytes = 0;
1834         max = get_num_var_ranges ();
1835         for (i = 0; i < max; i++)
1836         {
1837     	(*get_mtrr) (i, &base, &size, &type);
1838     	if (size == 0) usage_table[i] = 0;
1839     	else
1840     	{
1841     	    if (size < (0x100000 >> PAGE_SHIFT))
1842     	    {
1843     		/* less than 1MB */
1844     		factor = 'K';
1845     		size <<= PAGE_SHIFT - 10;
1846     	    }
1847     	    else
1848     	    {
1849     		factor = 'M';
1850     		size >>= 20 - PAGE_SHIFT;
1851     	    }
1852     	    sprintf
1853     		(ascii_buffer + ascii_buf_bytes,
1854     		 "reg%02i: base=0x%05lx000 (%4liMB), size=%4li%cB: %s, count=%d\n",
1855     		 i, base, base >> (20 - PAGE_SHIFT), size, factor,
1856     		 attrib_to_str (type), usage_table[i]);
1857     	    ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);
1858     	}
1859         }
1860         devfs_set_file_size (devfs_handle, ascii_buf_bytes);
1861     #  ifdef CONFIG_PROC_FS
1862         if (proc_root_mtrr)
1863     	proc_root_mtrr->size = ascii_buf_bytes;
1864     #  endif  /*  CONFIG_PROC_FS  */
1865     }   /*  End Function compute_ascii  */
1866     
1867     #endif  /*  USERSPACE_INTERFACE  */
1868     
1869     EXPORT_SYMBOL(mtrr_add);
1870     EXPORT_SYMBOL(mtrr_del);
1871     
1872     #ifdef CONFIG_SMP
1873     
1874     typedef struct
1875     {
1876         unsigned long base;
1877         unsigned long size;
1878         mtrr_type type;
1879     } arr_state_t;
1880     
1881     arr_state_t arr_state[8] __initdata =
1882     {
1883         {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL},
1884         {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}
1885     };
1886     
1887     unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 };
1888     
1889     static void __init cyrix_arr_init_secondary(void)
1890     {
1891         struct set_mtrr_context ctxt;
1892         int i;
1893     
1894         set_mtrr_prepare (&ctxt); /* flush cache and enable MAPEN */
1895     
1896          /* the CCRs are not contiguous */
1897         for(i=0; i<4; i++) setCx86(CX86_CCR0 + i, ccr_state[i]);
1898         for(   ; i<7; i++) setCx86(CX86_CCR4 + i, ccr_state[i]);
1899         for(i=0; i<8; i++)
1900           cyrix_set_arr_up(i,
1901             arr_state[i].base, arr_state[i].size, arr_state[i].type, FALSE);
1902     
1903         set_mtrr_done (&ctxt); /* flush cache and disable MAPEN */
1904     }   /*  End Function cyrix_arr_init_secondary  */
1905     
1906     #endif
1907     
1908     /*
1909      * On Cyrix 6x86(MX) and M II the ARR3 is special: it has connection
1910      * with the SMM (System Management Mode) mode. So we need the following:
1911      * Check whether SMI_LOCK (CCR3 bit 0) is set
1912      *   if it is set, write a warning message: ARR3 cannot be changed!
1913      *     (it cannot be changed until the next processor reset)
1914      *   if it is reset, then we can change it, set all the needed bits:
1915      *   - disable access to SMM memory through ARR3 range (CCR1 bit 7 reset)
1916      *   - disable access to SMM memory (CCR1 bit 2 reset)
1917      *   - disable SMM mode (CCR1 bit 1 reset)
1918      *   - disable write protection of ARR3 (CCR6 bit 1 reset)
1919      *   - (maybe) disable ARR3
1920      * Just to be sure, we enable ARR usage by the processor (CCR5 bit 5 set)
1921      */
1922     static void __init cyrix_arr_init(void)
1923     {
1924         struct set_mtrr_context ctxt;
1925         unsigned char ccr[7];
1926         int ccrc[7] = { 0, 0, 0, 0, 0, 0, 0 };
1927     #ifdef CONFIG_SMP
1928         int i;
1929     #endif
1930     
1931         set_mtrr_prepare (&ctxt); /* flush cache and enable MAPEN */
1932     
1933         /* Save all CCRs locally */
1934         ccr[0] = getCx86 (CX86_CCR0);
1935         ccr[1] = getCx86 (CX86_CCR1);
1936         ccr[2] = getCx86 (CX86_CCR2);
1937         ccr[3] = ctxt.ccr3;
1938         ccr[4] = getCx86 (CX86_CCR4);
1939         ccr[5] = getCx86 (CX86_CCR5);
1940         ccr[6] = getCx86 (CX86_CCR6);
1941     
1942         if (ccr[3] & 1)
1943         {
1944     	ccrc[3] = 1;
1945     	arr3_protected = 1;
1946         }
1947         else
1948         {
1949     	/* Disable SMM mode (bit 1), access to SMM memory (bit 2) and
1950     	 * access to SMM memory through ARR3 (bit 7).
1951     	 */
1952     	if (ccr[1] & 0x80) { ccr[1] &= 0x7f; ccrc[1] |= 0x80; }
1953     	if (ccr[1] & 0x04) { ccr[1] &= 0xfb; ccrc[1] |= 0x04; }
1954     	if (ccr[1] & 0x02) { ccr[1] &= 0xfd; ccrc[1] |= 0x02; }
1955     	arr3_protected = 0;
1956     	if (ccr[6] & 0x02) {
1957     	    ccr[6] &= 0xfd; ccrc[6] = 1; /* Disable write protection of ARR3 */
1958     	    setCx86 (CX86_CCR6, ccr[6]);
1959     	}
1960     	/* Disable ARR3. This is safe now that we disabled SMM. */
1961     	/* cyrix_set_arr_up (3, 0, 0, 0, FALSE); */
1962         }
1963         /* If we changed CCR1 in memory, change it in the processor, too. */
1964         if (ccrc[1]) setCx86 (CX86_CCR1, ccr[1]);
1965     
1966         /* Enable ARR usage by the processor */
1967         if (!(ccr[5] & 0x20))
1968         {
1969     	ccr[5] |= 0x20; ccrc[5] = 1;
1970     	setCx86 (CX86_CCR5, ccr[5]);
1971         }
1972     
1973     #ifdef CONFIG_SMP
1974         for(i=0; i<7; i++) ccr_state[i] = ccr[i];
1975         for(i=0; i<8; i++)
1976           cyrix_get_arr(i,
1977             &arr_state[i].base, &arr_state[i].size, &arr_state[i].type);
1978     #endif
1979     
1980         set_mtrr_done (&ctxt); /* flush cache and disable MAPEN */
1981     
1982         if ( ccrc[5] ) printk ("mtrr: ARR usage was not enabled, enabled manually\n");
1983         if ( ccrc[3] ) printk ("mtrr: ARR3 cannot be changed\n");
1984     /*
1985         if ( ccrc[1] & 0x80) printk ("mtrr: SMM memory access through ARR3 disabled\n");
1986         if ( ccrc[1] & 0x04) printk ("mtrr: SMM memory access disabled\n");
1987         if ( ccrc[1] & 0x02) printk ("mtrr: SMM mode disabled\n");
1988     */
1989         if ( ccrc[6] ) printk ("mtrr: ARR3 was write protected, unprotected\n");
1990     }   /*  End Function cyrix_arr_init  */
1991     
1992     /*
1993      *	Initialise the later (saner) Winchip MCR variant. In this version
1994      *	the BIOS can pass us the registers it has used (but not their values)
1995      *	and the control register is read/write
1996      */
1997      
1998     static void __init centaur_mcr1_init(void)
1999     {
2000         unsigned i;
2001         u32 lo, hi;
2002     
2003         /* Unfortunately, MCR's are read-only, so there is no way to
2004          * find out what the bios might have done.
2005          */
2006          
2007         rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
2008         if(((lo>>17)&7)==1)		/* Type 1 Winchip2 MCR */
2009         {
2010         	lo&= ~0x1C0;		/* clear key */
2011         	lo|= 0x040;		/* set key to 1 */
2012     	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);	/* unlock MCR */
2013         }    
2014         
2015         centaur_mcr_type = 1;
2016         
2017         /*
2018          *	Clear any unconfigured MCR's.
2019          */
2020     
2021         for (i = 0; i < 8; ++i)
2022         {
2023         	if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
2024         	{
2025         		if(!(lo & (1<<(9+i))))
2026     			wrmsr (MSR_IDT_MCR0 + i , 0, 0);
2027     		else
2028     			/*
2029     			 *	If the BIOS set up an MCR we cannot see it
2030     			 *	but we don't wish to obliterate it
2031     			 */
2032     			centaur_mcr_reserved |= (1<<i);
2033     	}
2034         }
2035         /*  
2036          *	Throw the main write-combining switch... 
2037          *	However if OOSTORE is enabled then people have already done far
2038          *  cleverer things and we should behave. 
2039          */
2040     
2041         lo |= 15;			/* Write combine enables */
2042         wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
2043     }   /*  End Function centaur_mcr1_init  */
2044     
2045     /*
2046      *	Initialise the original winchip with read only MCR registers
2047      *	no used bitmask for the BIOS to pass on and write only control
2048      */
2049      
2050     static void __init centaur_mcr0_init(void)
2051     {
2052         unsigned i;
2053     
2054         /* Unfortunately, MCR's are read-only, so there is no way to
2055          * find out what the bios might have done.
2056          */
2057          
2058         /* Clear any unconfigured MCR's.
2059          * This way we are sure that the centaur_mcr array contains the actual
2060          * values. The disadvantage is that any BIOS tweaks are thus undone.
2061          *
2062          */
2063         for (i = 0; i < 8; ++i)
2064         {
2065         	if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
2066     		wrmsr (MSR_IDT_MCR0 + i , 0, 0);
2067         }
2068     
2069         wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);	/* Write only */
2070     }   /*  End Function centaur_mcr0_init  */
2071     
2072     /*
2073      *	Initialise Winchip series MCR registers
2074      */
2075      
2076     static void __init centaur_mcr_init(void)
2077     {
2078         struct set_mtrr_context ctxt;
2079     
2080         set_mtrr_prepare (&ctxt);
2081     
2082         if(boot_cpu_data.x86_model==4)
2083         	centaur_mcr0_init();
2084         else if(boot_cpu_data.x86_model==8 || boot_cpu_data.x86_model == 9)
2085         	centaur_mcr1_init();
2086     
2087         set_mtrr_done (&ctxt);
2088     }   /*  End Function centaur_mcr_init  */
2089     
2090     static int __init mtrr_setup(void)
2091     {
2092         if ( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ) {
2093     	/* Intel (P6) standard MTRRs */
2094     	mtrr_if = MTRR_IF_INTEL;
2095     	get_mtrr = intel_get_mtrr;
2096     	set_mtrr_up = intel_set_mtrr_up;
2097     	switch (boot_cpu_data.x86_vendor) {
2098     
2099     	case X86_VENDOR_AMD:
2100     		/* The original Athlon docs said that
2101     		   total addressable memory is 44 bits wide.
2102     		   It was not really clear whether its MTRRs
2103     		   follow this or not. (Read: 44 or 36 bits).
2104     		   However, "x86-64_overview.pdf" explicitly
2105     		   states that "previous implementations support
2106     		   36 bit MTRRs" and also provides a way to
2107     		   query the width (in bits) of the physical
2108     		   addressable memory on the Hammer family.
2109     		 */
2110     		if (boot_cpu_data.x86 == 7 && (cpuid_eax(0x80000000) >= 0x80000008)) {
2111     			u32	phys_addr;
2112     			phys_addr = cpuid_eax(0x80000008) & 0xff ;
2113     			size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
2114     			size_and_mask = ~size_or_mask & 0xfff00000;
2115     			break;
2116     		}
2117     		size_or_mask  = 0xff000000; /* 36 bits */
2118     		size_and_mask = 0x00f00000;
2119     		break;
2120     
2121     	case X86_VENDOR_CENTAUR:
2122     		/* Cyrix III has Intel style MTRRs, but doesn't support PAE */
2123     		if (boot_cpu_data.x86 == 6 &&
2124     			(boot_cpu_data.x86_model == 6 ||
2125     			 boot_cpu_data.x86_model == 7)) {
2126     			size_or_mask  = 0xfff00000; /* 32 bits */
2127     			size_and_mask = 0;
2128     		}
2129     		break;
2130     
2131     	default:
2132     		/* Intel, etc. */
2133     		size_or_mask  = 0xff000000; /* 36 bits */
2134     		size_and_mask = 0x00f00000;
2135     		break;
2136     	}
2137     
2138         } else if ( test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ) {
2139     	/* Pre-Athlon (K6) AMD CPU MTRRs */
2140     	mtrr_if = MTRR_IF_AMD_K6;
2141     	get_mtrr = amd_get_mtrr;
2142     	set_mtrr_up = amd_set_mtrr_up;
2143     	size_or_mask  = 0xfff00000; /* 32 bits */
2144     	size_and_mask = 0;
2145         } else if ( test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ) {
2146     	/* Cyrix ARRs */
2147     	mtrr_if = MTRR_IF_CYRIX_ARR;
2148     	get_mtrr = cyrix_get_arr;
2149     	set_mtrr_up = cyrix_set_arr_up;
2150     	get_free_region = cyrix_get_free_region;
2151     	cyrix_arr_init();
2152     	size_or_mask  = 0xfff00000; /* 32 bits */
2153     	size_and_mask = 0;
2154         } else if ( test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) ) {
2155     	/* Centaur MCRs */
2156     	mtrr_if = MTRR_IF_CENTAUR_MCR;
2157     	get_mtrr = centaur_get_mcr;
2158     	set_mtrr_up = centaur_set_mcr_up;
2159     	get_free_region = centaur_get_free_region;
2160     	centaur_mcr_init();
2161     	size_or_mask  = 0xfff00000; /* 32 bits */
2162     	size_and_mask = 0;
2163         } else {
2164     	/* No supported MTRR interface */
2165     	mtrr_if = MTRR_IF_NONE;
2166         }
2167     
2168         printk ("mtrr: v%s Richard Gooch (rgooch@atnf.csiro.au)\n"
2169     	    "mtrr: detected mtrr type: %s\n",
2170     	    MTRR_VERSION, mtrr_if_name[mtrr_if]);
2171     
2172         return (mtrr_if != MTRR_IF_NONE);
2173     }   /*  End Function mtrr_setup  */
2174     
2175     #ifdef CONFIG_SMP
2176     
2177     static volatile unsigned long smp_changes_mask __initdata = 0;
2178     static struct mtrr_state smp_mtrr_state __initdata = {0, 0};
2179     
2180     void __init mtrr_init_boot_cpu(void)
2181     {
2182         if ( !mtrr_setup () )
2183     	return;
2184     
2185         if ( mtrr_if == MTRR_IF_INTEL ) {
2186     	/* Only for Intel MTRRs */
2187     	get_mtrr_state (&smp_mtrr_state);
2188         }
2189     }   /*  End Function mtrr_init_boot_cpu  */
2190     
2191     static void __init intel_mtrr_init_secondary_cpu(void)
2192     {
2193         unsigned long mask, count;
2194         struct set_mtrr_context ctxt;
2195     
2196         /*  Note that this is not ideal, since the cache is only flushed/disabled
2197     	for this CPU while the MTRRs are changed, but changing this requires
2198     	more invasive changes to the way the kernel boots  */
2199         set_mtrr_prepare (&ctxt);
2200         mask = set_mtrr_state (&smp_mtrr_state, &ctxt);
2201         set_mtrr_done (&ctxt);
2202         /*  Use the atomic bitops to update the global mask  */
2203         for (count = 0; count < sizeof mask * 8; ++count)
2204         {
2205     	if (mask & 0x01) set_bit (count, &smp_changes_mask);
2206     	mask >>= 1;
2207         }
2208     }   /*  End Function intel_mtrr_init_secondary_cpu  */
2209     
2210     void __init mtrr_init_secondary_cpu(void)
2211     {
2212         switch ( mtrr_if ) {
2213         case MTRR_IF_INTEL:
2214     	/* Intel (P6) standard MTRRs */
2215     	intel_mtrr_init_secondary_cpu();
2216     	break;
2217         case MTRR_IF_CYRIX_ARR:
2218     	/* This is _completely theoretical_!
2219     	 * I assume here that one day Cyrix will support Intel APIC.
2220     	 * In reality on non-Intel CPUs we won't even get to this routine.
2221     	 * Hopefully no one will plug two Cyrix processors in a dual P5 board.
2222     	 *  :-)
2223     	 */
2224     	cyrix_arr_init_secondary ();
2225     	break;
2226         case MTRR_IF_NONE:
2227     	break;
2228         default:
2229     	/* I see no MTRRs I can support in SMP mode... */
2230     	printk ("mtrr: SMP support incomplete for this vendor\n");
2231         }
2232     }   /*  End Function mtrr_init_secondary_cpu  */
2233     #endif  /*  CONFIG_SMP  */
2234     
2235     int __init mtrr_init(void)
2236     {
2237     #ifdef CONFIG_SMP
2238         /* mtrr_setup() should already have been called from mtrr_init_boot_cpu() */
2239     
2240         if ( mtrr_if == MTRR_IF_INTEL ) {
2241     	finalize_mtrr_state (&smp_mtrr_state);
2242     	mtrr_state_warn (smp_changes_mask);
2243         }
2244     #else
2245         if ( !mtrr_setup() )
2246     	return 0;		/* MTRRs not supported? */
2247     #endif
2248     
2249     #ifdef CONFIG_PROC_FS
2250         proc_root_mtrr = create_proc_entry ("mtrr", S_IWUSR | S_IRUGO, &proc_root);
2251         if (proc_root_mtrr) {
2252     	proc_root_mtrr->owner = THIS_MODULE;
2253     	proc_root_mtrr->proc_fops = &mtrr_fops;
2254         }
2255     #endif
2256         devfs_handle = devfs_register (NULL, "cpu/mtrr", DEVFS_FL_DEFAULT, 0, 0,
2257     				   S_IFREG | S_IRUGO | S_IWUSR,
2258     				   &mtrr_fops, NULL);
2259         init_table ();
2260         return 0;
2261     }   /*  End Function mtrr_init  */
2262     
2263     /*
2264      * Local Variables:
2265      * mode:c
2266      * c-file-style:"k&r"
2267      * c-basic-offset:4
2268      * End:
2269      */
2270