Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #include <linux/mm.h> |
2 | #include <linux/init.h> | |
3 | #include <asm/io.h> | |
4 | #include <asm/mtrr.h> | |
5 | #include <asm/msr.h> | |
96a388de | 6 | #include <asm/processor-cyrix.h> |
1da177e4 LT |
7 | #include "mtrr.h" |
8 | ||
9 | ||
10 | /* Put the processor into a state where MTRRs can be safely set */ | |
11 | void set_mtrr_prepare_save(struct set_mtrr_context *ctxt) | |
12 | { | |
13 | unsigned int cr0; | |
14 | ||
15 | /* Disable interrupts locally */ | |
16 | local_irq_save(ctxt->flags); | |
17 | ||
18 | if (use_intel() || is_cpu(CYRIX)) { | |
19 | ||
20 | /* Save value of CR4 and clear Page Global Enable (bit 7) */ | |
21 | if ( cpu_has_pge ) { | |
22 | ctxt->cr4val = read_cr4(); | |
17304383 | 23 | write_cr4(ctxt->cr4val & ~X86_CR4_PGE); |
1da177e4 LT |
24 | } |
25 | ||
26 | /* Disable and flush caches. Note that wbinvd flushes the TLBs as | |
27 | a side-effect */ | |
28 | cr0 = read_cr0() | 0x40000000; | |
29 | wbinvd(); | |
30 | write_cr0(cr0); | |
31 | wbinvd(); | |
32 | ||
33 | if (use_intel()) | |
34 | /* Save MTRR state */ | |
35 | rdmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi); | |
36 | else | |
37 | /* Cyrix ARRs - everything else were excluded at the top */ | |
38 | ctxt->ccr3 = getCx86(CX86_CCR3); | |
39 | } | |
40 | } | |
41 | ||
42 | void set_mtrr_cache_disable(struct set_mtrr_context *ctxt) | |
43 | { | |
44 | if (use_intel()) | |
45 | /* Disable MTRRs, and set the default type to uncached */ | |
46 | mtrr_wrmsr(MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, | |
47 | ctxt->deftype_hi); | |
48 | else if (is_cpu(CYRIX)) | |
49 | /* Cyrix ARRs - everything else were excluded at the top */ | |
50 | setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10); | |
51 | } | |
52 | ||
53 | /* Restore the processor after a set_mtrr_prepare */ | |
54 | void set_mtrr_done(struct set_mtrr_context *ctxt) | |
55 | { | |
56 | if (use_intel() || is_cpu(CYRIX)) { | |
57 | ||
58 | /* Flush caches and TLBs */ | |
59 | wbinvd(); | |
60 | ||
61 | /* Restore MTRRdefType */ | |
62 | if (use_intel()) | |
63 | /* Intel (P6) standard MTRRs */ | |
64 | mtrr_wrmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi); | |
65 | else | |
66 | /* Cyrix ARRs - everything else was excluded at the top */ | |
67 | setCx86(CX86_CCR3, ctxt->ccr3); | |
68 | ||
69 | /* Enable caches */ | |
70 | write_cr0(read_cr0() & 0xbfffffff); | |
71 | ||
72 | /* Restore value of CR4 */ | |
73 | if ( cpu_has_pge ) | |
74 | write_cr4(ctxt->cr4val); | |
75 | } | |
76 | /* Re-enable interrupts locally (if enabled previously) */ | |
77 | local_irq_restore(ctxt->flags); | |
78 | } | |
79 |