sh: Generalise the pte handling code for the fixmap path
[safe/jmp/linux-2.6] / arch / sh / mm / init.c
1 /*
2  * linux/arch/sh/mm/init.c
3  *
4  *  Copyright (C) 1999  Niibe Yutaka
5  *  Copyright (C) 2002 - 2007  Paul Mundt
6  *
7  *  Based on linux/arch/i386/mm/init.c:
8  *   Copyright (C) 1995  Linus Torvalds
9  */
10 #include <linux/mm.h>
11 #include <linux/swap.h>
12 #include <linux/init.h>
13 #include <linux/bootmem.h>
14 #include <linux/proc_fs.h>
15 #include <linux/pagemap.h>
16 #include <linux/percpu.h>
17 #include <linux/io.h>
18 #include <linux/dma-mapping.h>
19 #include <asm/mmu_context.h>
20 #include <asm/tlb.h>
21 #include <asm/cacheflush.h>
22 #include <asm/sections.h>
23 #include <asm/cache.h>
24
25 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
26 pgd_t swapper_pg_dir[PTRS_PER_PGD];
27
28 #ifdef CONFIG_SUPERH32
29 /*
30  * Handle trivial transitions between cached and uncached
31  * segments, making use of the 1:1 mapping relationship in
32  * 512MB lowmem.
33  *
34  * This is the offset of the uncached section from its cached alias.
35  * Default value only valid in 29 bit mode, in 32bit mode will be
36  * overridden in pmb_init.
37  */
38 unsigned long cached_to_uncached = P2SEG - P1SEG;
39 #endif
40
41 #ifdef CONFIG_MMU
42 static pte_t *__get_pte_phys(unsigned long addr)
43 {
44         pgd_t *pgd;
45         pud_t *pud;
46         pmd_t *pmd;
47         pte_t *pte;
48
49         pgd = pgd_offset_k(addr);
50         if (pgd_none(*pgd)) {
51                 pgd_ERROR(*pgd);
52                 return NULL;
53         }
54
55         pud = pud_alloc(NULL, pgd, addr);
56         if (unlikely(!pud)) {
57                 pud_ERROR(*pud);
58                 return NULL;
59         }
60
61         pmd = pmd_alloc(NULL, pud, addr);
62         if (unlikely(!pmd)) {
63                 pmd_ERROR(*pmd);
64                 return NULL;
65         }
66
67         pte = pte_offset_kernel(pmd, addr);
68         return pte;
69 }
70
71 static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
72 {
73         pte_t *pte;
74
75         pte = __get_pte_phys(addr);
76         if (!pte_none(*pte)) {
77                 pte_ERROR(*pte);
78                 return;
79         }
80
81         set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
82         local_flush_tlb_one(get_asid(), addr);
83
84         if (pgprot_val(prot) & _PAGE_WIRED)
85                 tlb_wire_entry(NULL, addr, *pte);
86 }
87
88 static void clear_pte_phys(unsigned long addr, pgprot_t prot)
89 {
90         pte_t *pte;
91
92         pte = __get_pte_phys(addr);
93
94         if (pgprot_val(prot) & _PAGE_WIRED)
95                 tlb_unwire_entry();
96
97         set_pte(pte, pfn_pte(0, __pgprot(0)));
98         local_flush_tlb_one(get_asid(), addr);
99 }
100
101 /*
102  * As a performance optimization, other platforms preserve the fixmap mapping
103  * across a context switch, we don't presently do this, but this could be done
104  * in a similar fashion as to the wired TLB interface that sh64 uses (by way
105  * of the memory mapped UTLB configuration) -- this unfortunately forces us to
106  * give up a TLB entry for each mapping we want to preserve. While this may be
107  * viable for a small number of fixmaps, it's not particularly useful for
108  * everything and needs to be carefully evaluated. (ie, we may want this for
109  * the vsyscall page).
110  *
111  * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass
112  * in at __set_fixmap() time to determine the appropriate behavior to follow.
113  *
114  *                                       -- PFM.
115  */
116 void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
117 {
118         unsigned long address = __fix_to_virt(idx);
119
120         if (idx >= __end_of_fixed_addresses) {
121                 BUG();
122                 return;
123         }
124
125         set_pte_phys(address, phys, prot);
126 }
127
128 void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot)
129 {
130         unsigned long address = __fix_to_virt(idx);
131
132         if (idx >= __end_of_fixed_addresses) {
133                 BUG();
134                 return;
135         }
136
137         clear_pte_phys(address, prot);
138 }
139
140 void __init page_table_range_init(unsigned long start, unsigned long end,
141                                          pgd_t *pgd_base)
142 {
143         pgd_t *pgd;
144         pud_t *pud;
145         pmd_t *pmd;
146         pte_t *pte;
147         int i, j, k;
148         unsigned long vaddr;
149
150         vaddr = start;
151         i = __pgd_offset(vaddr);
152         j = __pud_offset(vaddr);
153         k = __pmd_offset(vaddr);
154         pgd = pgd_base + i;
155
156         for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
157                 pud = (pud_t *)pgd;
158                 for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
159 #ifdef __PAGETABLE_PMD_FOLDED
160                         pmd = (pmd_t *)pud;
161 #else
162                         pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
163                         pud_populate(&init_mm, pud, pmd);
164                         pmd += k;
165 #endif
166                         for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
167                                 if (pmd_none(*pmd)) {
168                                         pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
169                                         pmd_populate_kernel(&init_mm, pmd, pte);
170                                         BUG_ON(pte != pte_offset_kernel(pmd, 0));
171                                 }
172                                 vaddr += PMD_SIZE;
173                         }
174                         k = 0;
175                 }
176                 j = 0;
177         }
178 }
179 #endif  /* CONFIG_MMU */
180
181 /*
182  * paging_init() sets up the page tables
183  */
184 void __init paging_init(void)
185 {
186         unsigned long max_zone_pfns[MAX_NR_ZONES];
187         unsigned long vaddr, end;
188         int nid;
189
190         /* We don't need to map the kernel through the TLB, as
191          * it is permanatly mapped using P1. So clear the
192          * entire pgd. */
193         memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
194
195         /* Set an initial value for the MMU.TTB so we don't have to
196          * check for a null value. */
197         set_TTB(swapper_pg_dir);
198
199         /*
200          * Populate the relevant portions of swapper_pg_dir so that
201          * we can use the fixmap entries without calling kmalloc.
202          * pte's will be filled in by __set_fixmap().
203          */
204         vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
205         end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
206         page_table_range_init(vaddr, end, swapper_pg_dir);
207
208         kmap_coherent_init();
209
210         memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
211
212         for_each_online_node(nid) {
213                 pg_data_t *pgdat = NODE_DATA(nid);
214                 unsigned long low, start_pfn;
215
216                 start_pfn = pgdat->bdata->node_min_pfn;
217                 low = pgdat->bdata->node_low_pfn;
218
219                 if (max_zone_pfns[ZONE_NORMAL] < low)
220                         max_zone_pfns[ZONE_NORMAL] = low;
221
222                 printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n",
223                        nid, start_pfn, low);
224         }
225
226         free_area_init_nodes(max_zone_pfns);
227
228         /* Set up the uncached fixmap */
229         set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
230 }
231
232 /*
233  * Early initialization for any I/O MMUs we might have.
234  */
235 static void __init iommu_init(void)
236 {
237         no_iommu_init();
238 }
239
240 void __init mem_init(void)
241 {
242         int codesize, datasize, initsize;
243         int nid;
244
245         iommu_init();
246
247         num_physpages = 0;
248         high_memory = NULL;
249
250         for_each_online_node(nid) {
251                 pg_data_t *pgdat = NODE_DATA(nid);
252                 unsigned long node_pages = 0;
253                 void *node_high_memory;
254
255                 num_physpages += pgdat->node_present_pages;
256
257                 if (pgdat->node_spanned_pages)
258                         node_pages = free_all_bootmem_node(pgdat);
259
260                 totalram_pages += node_pages;
261
262                 node_high_memory = (void *)__va((pgdat->node_start_pfn +
263                                                  pgdat->node_spanned_pages) <<
264                                                  PAGE_SHIFT);
265                 if (node_high_memory > high_memory)
266                         high_memory = node_high_memory;
267         }
268
269         /* Set this up early, so we can take care of the zero page */
270         cpu_cache_init();
271
272         /* clear the zero-page */
273         memset(empty_zero_page, 0, PAGE_SIZE);
274         __flush_wback_region(empty_zero_page, PAGE_SIZE);
275
276         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
277         datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
278         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
279
280         printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
281                "%dk data, %dk init)\n",
282                 nr_free_pages() << (PAGE_SHIFT-10),
283                 num_physpages << (PAGE_SHIFT-10),
284                 codesize >> 10,
285                 datasize >> 10,
286                 initsize >> 10);
287
288         /* Initialize the vDSO */
289         vsyscall_init();
290 }
291
292 void free_initmem(void)
293 {
294         unsigned long addr;
295
296         addr = (unsigned long)(&__init_begin);
297         for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
298                 ClearPageReserved(virt_to_page(addr));
299                 init_page_count(virt_to_page(addr));
300                 free_page(addr);
301                 totalram_pages++;
302         }
303         printk("Freeing unused kernel memory: %ldk freed\n",
304                ((unsigned long)&__init_end -
305                 (unsigned long)&__init_begin) >> 10);
306 }
307
308 #ifdef CONFIG_BLK_DEV_INITRD
309 void free_initrd_mem(unsigned long start, unsigned long end)
310 {
311         unsigned long p;
312         for (p = start; p < end; p += PAGE_SIZE) {
313                 ClearPageReserved(virt_to_page(p));
314                 init_page_count(virt_to_page(p));
315                 free_page(p);
316                 totalram_pages++;
317         }
318         printk("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
319 }
320 #endif
321
322 #ifdef CONFIG_MEMORY_HOTPLUG
323 int arch_add_memory(int nid, u64 start, u64 size)
324 {
325         pg_data_t *pgdat;
326         unsigned long start_pfn = start >> PAGE_SHIFT;
327         unsigned long nr_pages = size >> PAGE_SHIFT;
328         int ret;
329
330         pgdat = NODE_DATA(nid);
331
332         /* We only have ZONE_NORMAL, so this is easy.. */
333         ret = __add_pages(nid, pgdat->node_zones + ZONE_NORMAL,
334                                 start_pfn, nr_pages);
335         if (unlikely(ret))
336                 printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
337
338         return ret;
339 }
340 EXPORT_SYMBOL_GPL(arch_add_memory);
341
342 #ifdef CONFIG_NUMA
343 int memory_add_physaddr_to_nid(u64 addr)
344 {
345         /* Node 0 for now.. */
346         return 0;
347 }
348 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
349 #endif
350
351 #endif /* CONFIG_MEMORY_HOTPLUG */
352
353 #ifdef CONFIG_PMB
354 int __in_29bit_mode(void)
355 {
356         return !(ctrl_inl(PMB_PASCR) & PASCR_SE);
357 }
358 #endif /* CONFIG_PMB */