diff options
Diffstat (limited to 'include/asm-powerpc/highmem.h')
-rw-r--r-- | include/asm-powerpc/highmem.h | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/include/asm-powerpc/highmem.h b/include/asm-powerpc/highmem.h index f7b21ee302b4..5d99b6489d56 100644 --- a/include/asm-powerpc/highmem.h +++ b/include/asm-powerpc/highmem.h | |||
@@ -27,9 +27,7 @@ | |||
27 | #include <asm/kmap_types.h> | 27 | #include <asm/kmap_types.h> |
28 | #include <asm/tlbflush.h> | 28 | #include <asm/tlbflush.h> |
29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | 30 | #include <asm/fixmap.h> | |
31 | /* undef for production */ | ||
32 | #define HIGHMEM_DEBUG 1 | ||
33 | 31 | ||
34 | extern pte_t *kmap_pte; | 32 | extern pte_t *kmap_pte; |
35 | extern pgprot_t kmap_prot; | 33 | extern pgprot_t kmap_prot; |
@@ -40,14 +38,12 @@ extern pte_t *pkmap_page_table; | |||
40 | * easily, subsequent pte tables have to be allocated in one physical | 38 | * easily, subsequent pte tables have to be allocated in one physical |
41 | * chunk of RAM. | 39 | * chunk of RAM. |
42 | */ | 40 | */ |
43 | #define PKMAP_BASE CONFIG_HIGHMEM_START | ||
44 | #define LAST_PKMAP (1 << PTE_SHIFT) | 41 | #define LAST_PKMAP (1 << PTE_SHIFT) |
45 | #define LAST_PKMAP_MASK (LAST_PKMAP-1) | 42 | #define LAST_PKMAP_MASK (LAST_PKMAP-1) |
43 | #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) | ||
46 | #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) | 44 | #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) |
47 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | 45 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) |
48 | 46 | ||
49 | #define KMAP_FIX_BEGIN (PKMAP_BASE + 0x00400000UL) | ||
50 | |||
51 | extern void *kmap_high(struct page *page); | 47 | extern void *kmap_high(struct page *page); |
52 | extern void kunmap_high(struct page *page); | 48 | extern void kunmap_high(struct page *page); |
53 | 49 | ||
@@ -73,7 +69,7 @@ static inline void kunmap(struct page *page) | |||
73 | * be used in IRQ contexts, so in some (very limited) cases we need | 69 | * be used in IRQ contexts, so in some (very limited) cases we need |
74 | * it. | 70 | * it. |
75 | */ | 71 | */ |
76 | static inline void *kmap_atomic(struct page *page, enum km_type type) | 72 | static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) |
77 | { | 73 | { |
78 | unsigned int idx; | 74 | unsigned int idx; |
79 | unsigned long vaddr; | 75 | unsigned long vaddr; |
@@ -84,34 +80,39 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) | |||
84 | return page_address(page); | 80 | return page_address(page); |
85 | 81 | ||
86 | idx = type + KM_TYPE_NR*smp_processor_id(); | 82 | idx = type + KM_TYPE_NR*smp_processor_id(); |
87 | vaddr = KMAP_FIX_BEGIN + idx * PAGE_SIZE; | 83 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
88 | #ifdef HIGHMEM_DEBUG | 84 | #ifdef CONFIG_DEBUG_HIGHMEM |
89 | BUG_ON(!pte_none(*(kmap_pte+idx))); | 85 | BUG_ON(!pte_none(*(kmap_pte-idx))); |
90 | #endif | 86 | #endif |
91 | set_pte_at(&init_mm, vaddr, kmap_pte+idx, mk_pte(page, kmap_prot)); | 87 | set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot)); |
92 | flush_tlb_page(NULL, vaddr); | 88 | flush_tlb_page(NULL, vaddr); |
93 | 89 | ||
94 | return (void*) vaddr; | 90 | return (void*) vaddr; |
95 | } | 91 | } |
96 | 92 | ||
93 | static inline void *kmap_atomic(struct page *page, enum km_type type) | ||
94 | { | ||
95 | return kmap_atomic_prot(page, type, kmap_prot); | ||
96 | } | ||
97 | |||
97 | static inline void kunmap_atomic(void *kvaddr, enum km_type type) | 98 | static inline void kunmap_atomic(void *kvaddr, enum km_type type) |
98 | { | 99 | { |
99 | #ifdef HIGHMEM_DEBUG | 100 | #ifdef CONFIG_DEBUG_HIGHMEM |
100 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 101 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
101 | unsigned int idx = type + KM_TYPE_NR*smp_processor_id(); | 102 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); |
102 | 103 | ||
103 | if (vaddr < KMAP_FIX_BEGIN) { // FIXME | 104 | if (vaddr < __fix_to_virt(FIX_KMAP_END)) { |
104 | pagefault_enable(); | 105 | pagefault_enable(); |
105 | return; | 106 | return; |
106 | } | 107 | } |
107 | 108 | ||
108 | BUG_ON(vaddr != KMAP_FIX_BEGIN + idx * PAGE_SIZE); | 109 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); |
109 | 110 | ||
110 | /* | 111 | /* |
111 | * force other mappings to Oops if they'll try to access | 112 | * force other mappings to Oops if they'll try to access |
112 | * this pte without first remap it | 113 | * this pte without first remap it |
113 | */ | 114 | */ |
114 | pte_clear(&init_mm, vaddr, kmap_pte+idx); | 115 | pte_clear(&init_mm, vaddr, kmap_pte-idx); |
115 | flush_tlb_page(NULL, vaddr); | 116 | flush_tlb_page(NULL, vaddr); |
116 | #endif | 117 | #endif |
117 | pagefault_enable(); | 118 | pagefault_enable(); |
@@ -120,12 +121,14 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) | |||
120 | static inline struct page *kmap_atomic_to_page(void *ptr) | 121 | static inline struct page *kmap_atomic_to_page(void *ptr) |
121 | { | 122 | { |
122 | unsigned long idx, vaddr = (unsigned long) ptr; | 123 | unsigned long idx, vaddr = (unsigned long) ptr; |
124 | pte_t *pte; | ||
123 | 125 | ||
124 | if (vaddr < KMAP_FIX_BEGIN) | 126 | if (vaddr < FIXADDR_START) |
125 | return virt_to_page(ptr); | 127 | return virt_to_page(ptr); |
126 | 128 | ||
127 | idx = (vaddr - KMAP_FIX_BEGIN) >> PAGE_SHIFT; | 129 | idx = virt_to_fix(vaddr); |
128 | return pte_page(kmap_pte[idx]); | 130 | pte = kmap_pte - (idx - FIX_KMAP_BEGIN); |
131 | return pte_page(*pte); | ||
129 | } | 132 | } |
130 | 133 | ||
131 | #define flush_cache_kmaps() flush_cache_all() | 134 | #define flush_cache_kmaps() flush_cache_all() |