init.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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