File: /usr/src/linux/arch/ppc/mm/init.c

1     /*
2      * BK Id: SCCS/s.init.c 1.34 08/20/01 22:12:43 paulus
3      */
4     /*
5      *  PowerPC version 
6      *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
7      *
8      *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
9      *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
10      *    Copyright (C) 1996 Paul Mackerras
11      *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
12      *
13      *  Derived from "arch/i386/mm/init.c"
14      *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
15      *
16      *  This program is free software; you can redistribute it and/or
17      *  modify it under the terms of the GNU General Public License
18      *  as published by the Free Software Foundation; either version
19      *  2 of the License, or (at your option) any later version.
20      *
21      */
22     
23     #include <linux/config.h>
24     #include <linux/sched.h>
25     #include <linux/kernel.h>
26     #include <linux/errno.h>
27     #include <linux/string.h>
28     #include <linux/types.h>
29     #include <linux/mm.h>
30     #include <linux/stddef.h>
31     #include <linux/init.h>
32     #include <linux/bootmem.h>
33     #include <linux/highmem.h>
34     #ifdef CONFIG_BLK_DEV_INITRD
35     #include <linux/blk.h>		/* for initrd_* */
36     #endif
37     
38     #include <asm/pgalloc.h>
39     #include <asm/prom.h>
40     #include <asm/io.h>
41     #include <asm/mmu_context.h>
42     #include <asm/pgtable.h>
43     #include <asm/mmu.h>
44     #include <asm/smp.h>
45     #include <asm/machdep.h>
46     #include <asm/btext.h>
47     
48     #include "mem_pieces.h"
49     #include "mmu_decl.h"
50     
51     #define MAX_LOW_MEM	(0xF0000000UL - KERNELBASE)
52     
53     void *end_of_DRAM;
54     unsigned long total_memory;
55     unsigned long total_lowmem;
56     
57     int mem_init_done;
58     int init_bootmem_done;
59     int boot_mapsize;
60     unsigned long totalram_pages;
61     unsigned long totalhigh_pages;
62     
63     extern char _end[];
64     extern char etext[], _stext[];
65     extern char __init_begin, __init_end;
66     extern char __prep_begin, __prep_end;
67     extern char __chrp_begin, __chrp_end;
68     extern char __pmac_begin, __pmac_end;
69     extern char __openfirmware_begin, __openfirmware_end;
70     
71     #ifdef CONFIG_HIGHMEM
72     pte_t *kmap_pte;
73     pgprot_t kmap_prot;
74     #endif
75     
76     void MMU_init(void);
77     void set_phys_avail(unsigned long total_ram);
78     
79     /* XXX should be in current.h  -- paulus */
80     extern struct task_struct *current_set[NR_CPUS];
81     
82     char *klimit = _end;
83     struct mem_pieces phys_avail;
84     
85     extern char *sysmap; 
86     extern unsigned long sysmap_size;
87     
88     /*
89      * this tells the system to map all of ram with the segregs
90      * (i.e. page tables) instead of the bats.
91      * -- Cort
92      */
93     int __map_without_bats;
94     
95     /* max amount of RAM to use */
96     unsigned long __max_memory;
97     /* max amount of low RAM to map in */
98     unsigned long __max_low_memory = MAX_LOW_MEM;
99     
100     int do_check_pgt_cache(int low, int high)
101     {
102     	int freed = 0;
103     	if (pgtable_cache_size > high) {
104     		do {
105                             if (pgd_quicklist) {
106     				free_pgd_slow(get_pgd_fast());
107     				freed++;
108     			}
109     			if (pte_quicklist) {
110     				pte_free_slow(pte_alloc_one_fast(NULL, 0));
111     				freed++;
112     			}
113     		} while (pgtable_cache_size > low);
114     	}
115     	return freed;
116     }
117     
118     void show_mem(void)
119     {
120     	int i,free = 0,total = 0,reserved = 0;
121     	int shared = 0, cached = 0;
122     	struct task_struct *p;
123     	int highmem = 0;
124     
125     	printk("Mem-info:\n");
126     	show_free_areas();
127     	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
128     	i = max_mapnr;
129     	while (i-- > 0) {
130     		total++;
131     		if (PageHighMem(mem_map+i))
132     			highmem++;
133     		if (PageReserved(mem_map+i))
134     			reserved++;
135     		else if (PageSwapCache(mem_map+i))
136     			cached++;
137     		else if (!page_count(mem_map+i))
138     			free++;
139     		else
140     			shared += atomic_read(&mem_map[i].count) - 1;
141     	}
142     	printk("%d pages of RAM\n",total);
143     	printk("%d pages of HIGHMEM\n", highmem);
144     	printk("%d free pages\n",free);
145     	printk("%d reserved pages\n",reserved);
146     	printk("%d pages shared\n",shared);
147     	printk("%d pages swap cached\n",cached);
148     	printk("%d pages in page table cache\n",(int)pgtable_cache_size);
149     	show_buffers();
150     	printk("%-8s %3s %8s %8s %8s %9s %8s", "Process", "Pid",
151     	       "Ctx", "Ctx<<4", "Last Sys", "pc", "task");
152     #ifdef CONFIG_SMP
153     	printk(" %3s", "CPU");
154     #endif /* CONFIG_SMP */
155     	printk("\n");
156     	for_each_task(p)
157     	{
158     		printk("%-8.8s %3d %8ld %8ld %8ld %c%08lx %08lx ",
159     		       p->comm,p->pid,
160     		       (p->mm)?p->mm->context:0,
161     		       (p->mm)?(p->mm->context<<4):0,
162     		       p->thread.last_syscall,
163     		       (p->thread.regs)?user_mode(p->thread.regs) ? 'u' : 'k' : '?',
164     		       (p->thread.regs)?p->thread.regs->nip:0,
165     		       (ulong)p);
166     		{
167     			int iscur = 0;
168     #ifdef CONFIG_SMP
169     			printk("%3d ", p->processor);
170     			if ( (p->processor != NO_PROC_ID) &&
171     			     (p == current_set[p->processor]) )
172     			{
173     				iscur = 1;
174     				printk("current");
175     			}
176     #else
177     			if ( p == current )
178     			{
179     				iscur = 1;
180     				printk("current");
181     			}
182     			
183     			if ( p == last_task_used_math )
184     			{
185     				if ( iscur )
186     					printk(",");
187     				printk("last math");
188     			}			
189     #endif /* CONFIG_SMP */
190     			printk("\n");
191     		}
192     	}
193     }
194     
195     void si_meminfo(struct sysinfo *val)
196     {
197     	val->totalram = totalram_pages;
198     	val->sharedram = 0;
199     	val->freeram = nr_free_pages();
200     	val->bufferram = atomic_read(&buffermem_pages);
201     	val->totalhigh = totalhigh_pages;
202     	val->freehigh = nr_free_highpages();
203     	val->mem_unit = PAGE_SIZE;
204     }
205     
206     /* Free up now-unused memory */
207     static void free_sec(unsigned long start, unsigned long end, const char *name)
208     {
209     	unsigned long cnt = 0;
210     
211     	while (start < end) {
212     		ClearPageReserved(virt_to_page(start));
213     		set_page_count(virt_to_page(start), 1);
214     		free_page(start);
215     		cnt++;
216     		start += PAGE_SIZE;
217      	}
218     	if (cnt) {
219     		printk(" %ldk %s", cnt << (PAGE_SHIFT - 10), name);
220     		totalram_pages += cnt;
221     	}
222     }
223     
224     void free_initmem(void)
225     {
226     #define FREESEC(TYPE) \
227     	free_sec((unsigned long)(&__ ## TYPE ## _begin), \
228     		 (unsigned long)(&__ ## TYPE ## _end), \
229     		 #TYPE);
230     
231     	printk ("Freeing unused kernel memory:");
232     	FREESEC(init);
233     	if (_machine != _MACH_Pmac)
234     		FREESEC(pmac);
235     	if (_machine != _MACH_chrp)
236     		FREESEC(chrp);
237     	if (_machine != _MACH_prep)
238     		FREESEC(prep);
239     	if (!have_of)
240     		FREESEC(openfirmware);
241      	printk("\n");
242     #undef FREESEC
243     }
244     
245     #ifdef CONFIG_BLK_DEV_INITRD
246     void free_initrd_mem(unsigned long start, unsigned long end)
247     {
248     	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
249     
250     	for (; start < end; start += PAGE_SIZE) {
251     		ClearPageReserved(virt_to_page(start));
252     		set_page_count(virt_to_page(start), 1);
253     		free_page(start);
254     		totalram_pages++;
255     	}
256     }
257     #endif
258     
259     /*
260      * Check for command-line options that affect what MMU_init will do.
261      */
262     void MMU_setup(void)
263     {
264     	/* Check for nobats option (used in mapin_ram). */
265     	if (strstr(cmd_line, "nobats")) {
266     		__map_without_bats = 1;
267     	}
268     
269     	/* Look for mem= option on command line */
270     	if (strstr(cmd_line, "mem=")) {
271     		char *p, *q;
272     		unsigned long maxmem = 0;
273     
274     		for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
275     			q = p + 4;
276     			if (p > cmd_line && p[-1] != ' ')
277     				continue;
278     			maxmem = simple_strtoul(q, &q, 0);
279     			if (*q == 'k' || *q == 'K') {
280     				maxmem <<= 10;
281     				++q;
282     			} else if (*q == 'm' || *q == 'M') {
283     				maxmem <<= 20;
284     				++q;
285     			}
286     		}
287     		__max_memory = maxmem;
288     	}
289     }
290     
291     /*
292      * MMU_init sets up the basic memory mappings for the kernel,
293      * including both RAM and possibly some I/O regions,
294      * and sets up the page tables and the MMU hardware ready to go.
295      */
296     void __init MMU_init(void)
297     {
298     	if (ppc_md.progress)
299     		ppc_md.progress("MMU:enter", 0x111);
300     
301     	/* parse args from command line */
302     	MMU_setup();
303     
304     	/*
305     	 * Figure out how much memory we have, how much
306     	 * is lowmem, and how much is highmem.
307     	 */
308     	total_memory = ppc_md.find_end_of_memory();
309     
310     	if (__max_memory && total_memory > __max_memory)
311     		total_memory = __max_memory;
312     	total_lowmem = total_memory;
313     	if (total_lowmem > __max_low_memory) {
314     		total_lowmem = __max_low_memory;
315     #ifndef CONFIG_HIGHMEM
316     		total_memory = total_lowmem;
317     #endif /* CONFIG_HIGHMEM */
318     	}
319     	end_of_DRAM = __va(total_lowmem);
320     	set_phys_avail(total_lowmem);
321     
322     	/* Initialize the MMU hardware */
323     	if (ppc_md.progress)
324     		ppc_md.progress("MMU:hw init", 0x300);
325     	MMU_init_hw();
326     
327     	/* Map in all of RAM starting at KERNELBASE */
328     	if (ppc_md.progress)
329     		ppc_md.progress("MMU:mapin", 0x301);
330     	mapin_ram();
331     
332     #ifdef CONFIG_HIGHMEM
333     	ioremap_base = PKMAP_BASE;
334     #else
335     	ioremap_base = 0xfe000000UL;	/* for now, could be 0xfffff000 */
336     #endif /* CONFIG_HIGHMEM */
337     	ioremap_bot = ioremap_base;
338     
339     	/* Map in I/O resources */
340     	if (ppc_md.progress)
341     		ppc_md.progress("MMU:setio", 0x302);
342     	if (ppc_md.setup_io_mappings)
343     		ppc_md.setup_io_mappings();
344     
345     	/* Initialize the context management stuff */
346     	mmu_context_init();
347     
348     	if (ppc_md.progress)
349     		ppc_md.progress("MMU:exit", 0x211);
350     
351     #ifdef CONFIG_BOOTX_TEXT
352     	/* Must be done last, or ppc_md.progress will die */
353     	if (have_of)
354     		map_boot_text();
355     #endif
356     }
357     
358     /* This is only called until mem_init is done. */
359     void __init *early_get_page(void)
360     {
361     	void *p;
362     
363     	if (init_bootmem_done) {
364     		p = alloc_bootmem_pages(PAGE_SIZE);
365     	} else {
366     		p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
367     	}
368     	return p;
369     }
370     
371     /*
372      * Initialize the bootmem system and give it all the memory we
373      * have available.
374      */
375     void __init do_init_bootmem(void)
376     {
377     	unsigned long start, size;
378     	int i;
379     
380     	/*
381     	 * Find an area to use for the bootmem bitmap.
382     	 * We look for the first area which is at least
383     	 * 128kB in length (128kB is enough for a bitmap
384     	 * for 4GB of memory, using 4kB pages), plus 1 page
385     	 * (in case the address isn't page-aligned).
386     	 */
387     	start = 0;
388     	size = 0;
389     	for (i = 0; i < phys_avail.n_regions; ++i) {
390     		unsigned long a = phys_avail.regions[i].address;
391     		unsigned long s = phys_avail.regions[i].size;
392     		if (s <= size)
393     			continue;
394     		start = a;
395     		size = s;
396     		if (s >= 33 * PAGE_SIZE)
397     			break;
398     	}
399     	start = PAGE_ALIGN(start);
400     
401     	boot_mapsize = init_bootmem(start >> PAGE_SHIFT,
402     				    total_lowmem >> PAGE_SHIFT);
403     
404     	/* remove the bootmem bitmap from the available memory */
405     	mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
406     
407     	/* add everything in phys_avail into the bootmem map */
408     	for (i = 0; i < phys_avail.n_regions; ++i)
409     		free_bootmem(phys_avail.regions[i].address,
410     			     phys_avail.regions[i].size);
411     
412     	init_bootmem_done = 1;
413     }
414     
415     /*
416      * paging_init() sets up the page tables - in fact we've already done this.
417      */
418     void __init paging_init(void)
419     {
420     	unsigned long zones_size[MAX_NR_ZONES], i;
421     
422     #ifdef CONFIG_HIGHMEM
423     	map_page(PKMAP_BASE, 0, 0);	/* XXX gross */
424     	pkmap_page_table = pte_offset(pmd_offset(pgd_offset_k(PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
425     	map_page(KMAP_FIX_BEGIN, 0, 0);	/* XXX gross */
426     	kmap_pte = pte_offset(pmd_offset(pgd_offset_k(KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
427     	kmap_prot = PAGE_KERNEL;
428     #endif /* CONFIG_HIGHMEM */
429     
430     	/*
431     	 * All pages are DMA-able so we put them all in the DMA zone.
432     	 */
433     	zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
434     	for (i = 1; i < MAX_NR_ZONES; i++)
435     		zones_size[i] = 0;
436     
437     #ifdef CONFIG_HIGHMEM
438     	zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
439     #endif /* CONFIG_HIGHMEM */
440     
441     	free_area_init(zones_size);
442     }
443     
444     void __init mem_init(void)
445     {
446     	unsigned long addr;
447     	int codepages = 0;
448     	int datapages = 0;
449     	int initpages = 0;
450     #ifdef CONFIG_HIGHMEM
451     	unsigned long highmem_mapnr;
452     
453     	highmem_mapnr = total_lowmem >> PAGE_SHIFT;
454     	highmem_start_page = mem_map + highmem_mapnr;
455     	max_mapnr = total_memory >> PAGE_SHIFT;
456     #else
457     	max_mapnr = max_low_pfn;
458     #endif /* CONFIG_HIGHMEM */
459     
460     	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
461     	num_physpages = max_mapnr;	/* RAM is assumed contiguous */
462     
463     	totalram_pages += free_all_bootmem();
464     
465     #ifdef CONFIG_BLK_DEV_INITRD
466     	/* if we are booted from BootX with an initial ramdisk,
467     	   make sure the ramdisk pages aren't reserved. */
468     	if (initrd_start) {
469     		for (addr = initrd_start; addr < initrd_end; addr += PAGE_SIZE)
470     			ClearPageReserved(virt_to_page(addr));
471     	}
472     #endif /* CONFIG_BLK_DEV_INITRD */
473     
474     #if defined(CONFIG_ALL_PPC)	
475     	/* mark the RTAS pages as reserved */
476     	if ( rtas_data )
477     		for (addr = (ulong)__va(rtas_data);
478     		     addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ;
479     		     addr += PAGE_SIZE)
480     			SetPageReserved(virt_to_page(addr));
481     #endif /* defined(CONFIG_ALL_PPC) */
482     	if ( sysmap )
483     		for (addr = (unsigned long)sysmap;
484     		     addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
485     		     addr += PAGE_SIZE)
486     			SetPageReserved(virt_to_page(addr));
487     	
488     	for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM;
489     	     addr += PAGE_SIZE) {
490     		if (!PageReserved(virt_to_page(addr)))
491     			continue;
492     		if (addr < (ulong) etext)
493     			codepages++;
494     		else if (addr >= (unsigned long)&__init_begin
495     			 && addr < (unsigned long)&__init_end)
496     			initpages++;
497     		else if (addr < (ulong) klimit)
498     			datapages++;
499     	}
500     
501     #ifdef CONFIG_HIGHMEM
502     	{
503     		unsigned long pfn;
504     
505     		for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
506     			struct page *page = mem_map + pfn;
507     
508     			ClearPageReserved(page);
509     			set_bit(PG_highmem, &page->flags);
510     			atomic_set(&page->count, 1);
511     			__free_page(page);
512     			totalhigh_pages++;
513     		}
514     		totalram_pages += totalhigh_pages;
515     	}
516     #endif /* CONFIG_HIGHMEM */
517     
518             printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
519     	       (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
520     	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
521     	       initpages<< (PAGE_SHIFT-10),
522     	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
523     	if (sysmap)
524     		printk("System.map loaded at 0x%08x for debugger, size: %ld bytes\n",
525     			(unsigned int)sysmap, sysmap_size);
526     	mem_init_done = 1;
527     }
528     
529     /*
530      * Set phys_avail to the amount of physical memory,
531      * less the kernel text/data/bss.
532      */
533     void __init
534     set_phys_avail(unsigned long total_memory)
535     {
536     	unsigned long kstart, ksize;
537     
538     	/*
539     	 * Initially, available physical memory is equivalent to all
540     	 * physical memory.
541     	 */
542     
543     	phys_avail.regions[0].address = 0;
544     	phys_avail.regions[0].size = total_memory;
545     	phys_avail.n_regions = 1;
546     
547     	/*
548     	 * Map out the kernel text/data/bss from the available physical
549     	 * memory.
550     	 */
551     
552     	kstart = __pa(_stext);	/* should be 0 */
553     	ksize = PAGE_ALIGN(klimit - _stext);
554     
555     	mem_pieces_remove(&phys_avail, kstart, ksize, 0);
556     	mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
557     
558     #if defined(CONFIG_BLK_DEV_INITRD)
559     	/* Remove the init RAM disk from the available memory. */
560     	if (initrd_start) {
561     		mem_pieces_remove(&phys_avail, __pa(initrd_start),
562     				  initrd_end - initrd_start, 1);
563     	}
564     #endif /* CONFIG_BLK_DEV_INITRD */
565     #ifdef CONFIG_ALL_PPC
566     	/* remove the RTAS pages from the available memory */
567     	if (rtas_data)
568     		mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
569     	/* remove the sysmap pages from the available memory */
570     	if (sysmap)
571     		mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1);
572     #endif /* CONFIG_ALL_PPC */
573     }
574     
575     /* Mark some memory as reserved by removing it from phys_avail. */
576     void __init reserve_phys_mem(unsigned long start, unsigned long size)
577     {
578     	mem_pieces_remove(&phys_avail, start, size, 1);
579     }
580     
581     void flush_page_to_ram(struct page *page)
582     {
583     	unsigned long vaddr = (unsigned long) kmap(page);
584     	__flush_page_to_ram(vaddr);
585     	kunmap(page);
586     }
587     
588     /*
589      * set_pte stores a linux PTE into the linux page table.
590      * On machines which use an MMU hash table we avoid changing the
591      * _PAGE_HASHPTE bit.
592      */
593     void set_pte(pte_t *ptep, pte_t pte)
594     {
595     #if _PAGE_HASHPTE != 0
596     	pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
597     #else
598     	*ptep = pte;
599     #endif
600     }
601