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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/cris/mm/init.c
  3.  *
  4.  *  Copyright (C) 1995  Linus Torvalds
  5.  *  Copyright (C) 2000,2001  Axis Communications AB
  6.  *
  7.  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  8.  *
  9.  *  $Log: init.c,v $
  10.  *  Revision 1.31  2001/11/13 16:22:00  bjornw
  11.  *  Skip calculating totalram and sharedram in si_meminfo
  12.  *
  13.  *  Revision 1.30  2001/11/12 19:02:10  pkj
  14.  *  Fixed compiler warnings.
  15.  *
  16.  *  Revision 1.29  2001/07/25 16:09:50  bjornw
  17.  *  val->sharedram will stay 0
  18.  *
  19.  *  Revision 1.28  2001/06/28 16:30:17  bjornw
  20.  *  Oops. This needs to wait until 2.4.6 is merged
  21.  *
  22.  *  Revision 1.27  2001/06/28 14:04:07  bjornw
  23.  *  Fill in sharedram
  24.  *
  25.  *  Revision 1.26  2001/06/18 06:36:02  hp
  26.  *  Enable free_initmem of __init-type pages
  27.  *
  28.  *  Revision 1.25  2001/06/13 00:02:23  bjornw
  29.  *  Use a separate variable to store the current pgd to avoid races in schedule
  30.  *
  31.  *  Revision 1.24  2001/05/15 00:52:20  hp
  32.  *  Only map segment 0xa as seg if CONFIG_JULIETTE
  33.  *
  34.  *  Revision 1.23  2001/04/04 14:35:40  bjornw
  35.  *  * Removed get_pte_slow and friends (2.4.3 change)
  36.  *  * Removed bad_pmd handling (2.4.3 change)
  37.  *
  38.  *  Revision 1.22  2001/04/04 13:38:04  matsfg
  39.  *  Moved ioremap to a separate function instead
  40.  *
  41.  *  Revision 1.21  2001/03/27 09:28:33  bjornw
  42.  *  ioremap used too early - lets try it in mem_init instead
  43.  *
  44.  *  Revision 1.20  2001/03/23 07:39:21  starvik
  45.  *  Corrected according to review remarks
  46.  *
  47.  *  Revision 1.19  2001/03/15 14:25:17  bjornw
  48.  *  More general shadow registers and ioremaped addresses for external I/O
  49.  *
  50.  *  Revision 1.18  2001/02/23 12:46:44  bjornw
  51.  *  * 0xc was not CSE1; 0x8 is, same as uncached flash, so we move the uncached
  52.  *    flash during CRIS_LOW_MAP from 0xe to 0x8 so both the flash and the I/O
  53.  *    is mapped straight over (for !CRIS_LOW_MAP the uncached flash is still 0xe)
  54.  *
  55.  *  Revision 1.17  2001/02/22 15:05:21  bjornw
  56.  *  Map 0x9 straight over during LOW_MAP to allow for memory mapped LEDs
  57.  *
  58.  *  Revision 1.16  2001/02/22 15:02:35  bjornw
  59.  *  Map 0xc straight over during LOW_MAP to allow for memory mapped I/O
  60.  *
  61.  *  Revision 1.15  2001/01/10 21:12:10  bjornw
  62.  *  loops_per_sec -> loops_per_jiffy
  63.  *
  64.  *  Revision 1.14  2000/11/22 16:23:20  bjornw
  65.  *  Initialize totalhigh counters to 0 to make /proc/meminfo look nice.
  66.  *
  67.  *  Revision 1.13  2000/11/21 16:37:51  bjornw
  68.  *  Temporarily disable initmem freeing
  69.  *
  70.  *  Revision 1.12  2000/11/21 13:55:07  bjornw
  71.  *  Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type
  72.  *
  73.  *  Revision 1.11  2000/10/06 12:38:22  bjornw
  74.  *  Cast empty_bad_page correctly (should really be of * type from the start..
  75.  *
  76.  *  Revision 1.10  2000/10/04 16:53:57  bjornw
  77.  *  Fix memory-map due to LX features
  78.  *
  79.  *  Revision 1.9  2000/09/13 15:47:49  bjornw
  80.  *  Wrong count in reserved-pages loop
  81.  *
  82.  *  Revision 1.8  2000/09/13 14:35:10  bjornw
  83.  *  2.4.0-test8 added a new arg to free_area_init_node
  84.  *
  85.  *  Revision 1.7  2000/08/17 15:35:55  bjornw
  86.  *  2.4.0-test6 removed MAP_NR and inserted virt_to_page
  87.  *
  88.  *
  89.  */
  90. #include <linux/config.h>
  91. #include <linux/signal.h>
  92. #include <linux/sched.h>
  93. #include <linux/kernel.h>
  94. #include <linux/errno.h>
  95. #include <linux/string.h>
  96. #include <linux/types.h>
  97. #include <linux/ptrace.h>
  98. #include <linux/mman.h>
  99. #include <linux/mm.h>
  100. #include <linux/swap.h>
  101. #include <linux/smp.h>
  102. #include <linux/bootmem.h>
  103. #include <asm/system.h>
  104. #include <asm/segment.h>
  105. #include <asm/pgalloc.h>
  106. #include <asm/pgtable.h>
  107. #include <asm/dma.h>
  108. #include <asm/svinto.h>
  109. #include <asm/io.h>
  110. #include <asm/mmu_context.h>
  111. static unsigned long totalram_pages;
  112. struct pgtable_cache_struct quicklists;  /* see asm/pgalloc.h */
  113. const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lxn";
  114. extern void die_if_kernel(char *,struct pt_regs *,long);
  115. extern void show_net_buffers(void);
  116. extern void tlb_init(void);
  117. unsigned long empty_zero_page;
  118. /* trim the page-table cache if necessary */
  119. int 
  120. do_check_pgt_cache(int low, int high)
  121. {
  122.         int freed = 0;
  123.         if(pgtable_cache_size > high) {
  124.                 do {
  125.                         if(pgd_quicklist) {
  126.                                 free_pgd_slow(get_pgd_fast());
  127.                                 freed++;
  128.                         }
  129.                         if(pmd_quicklist) {
  130.                                 pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
  131.                                 freed++;
  132.                         }
  133.                         if(pte_quicklist) {
  134.                                 pte_free_slow(pte_alloc_one_fast(NULL, 0));
  135. freed++;
  136.                         }
  137.                 } while(pgtable_cache_size > low);
  138.         }
  139.         return freed;
  140. }
  141. void 
  142. show_mem(void)
  143. {
  144. int i,free = 0,total = 0,cached = 0, reserved = 0, nonshared = 0;
  145. int shared = 0;
  146. printk("nMem-info:n");
  147. show_free_areas();
  148. printk("Free swap:       %6dkBn",nr_swap_pages<<(PAGE_SHIFT-10));
  149. i = max_mapnr;
  150. while (i-- > 0) {
  151. total++;
  152. if (PageReserved(mem_map+i))
  153. reserved++;
  154. else if (PageSwapCache(mem_map+i))
  155. cached++;
  156. else if (!page_count(mem_map+i))
  157. free++;
  158. else if (page_count(mem_map+i) == 1)
  159. nonshared++;
  160. else
  161. shared += page_count(mem_map+i) - 1;
  162. }
  163. printk("%d pages of RAMn",total);
  164. printk("%d free pagesn",free);
  165. printk("%d reserved pagesn",reserved);
  166. printk("%d pages nonsharedn",nonshared);
  167. printk("%d pages sharedn",shared);
  168. printk("%d pages swap cachedn",cached);
  169. printk("%ld pages in page table cachen",pgtable_cache_size);
  170. show_buffers();
  171. }
  172. /*
  173.  * The kernel is already mapped with a kernel segment at kseg_c so 
  174.  * we don't need to map it with a page table. However head.S also
  175.  * temporarily mapped it at kseg_4 so we should set up the ksegs again,
  176.  * clear the TLB and do some other paging setup stuff.
  177.  */
  178. void __init 
  179. paging_init(void)
  180. {
  181. int i;
  182. unsigned long zones_size[MAX_NR_ZONES];
  183. printk("Setting up paging and the MMU.n");
  184. /* clear out the init_mm.pgd that will contain the kernel's mappings */
  185. for(i = 0; i < PTRS_PER_PGD; i++)
  186. swapper_pg_dir[i] = __pgd(0);
  187. /* make sure the current pgd table points to something sane
  188.  * (even if it is most probably not used until the next 
  189.  *  switch_mm)
  190.  */
  191. current_pgd = init_mm.pgd;
  192. /* initialise the TLB (tlb.c) */
  193. tlb_init();
  194. /* see README.mm for details on the KSEG setup */
  195. #ifndef CONFIG_CRIS_LOW_MAP
  196. /* This code is for the corrected Etrax-100 LX version 2... */
  197. *R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) | /* cached flash */
  198. IO_STATE(R_MMU_KSEG, seg_e, seg  ) | /* uncached flash */
  199. IO_STATE(R_MMU_KSEG, seg_d, page ) | /* vmalloc area */
  200. IO_STATE(R_MMU_KSEG, seg_c, seg  ) | /* kernel area */
  201. IO_STATE(R_MMU_KSEG, seg_b, seg  ) | /* kernel reg area */
  202. IO_STATE(R_MMU_KSEG, seg_a, page ) | /* user area */
  203. IO_STATE(R_MMU_KSEG, seg_9, page ) |
  204. IO_STATE(R_MMU_KSEG, seg_8, page ) |
  205. IO_STATE(R_MMU_KSEG, seg_7, page ) |
  206. IO_STATE(R_MMU_KSEG, seg_6, page ) |
  207. IO_STATE(R_MMU_KSEG, seg_5, page ) |
  208. IO_STATE(R_MMU_KSEG, seg_4, page ) |
  209. IO_STATE(R_MMU_KSEG, seg_3, page ) |
  210. IO_STATE(R_MMU_KSEG, seg_2, page ) |
  211. IO_STATE(R_MMU_KSEG, seg_1, page ) |
  212. IO_STATE(R_MMU_KSEG, seg_0, page ) );
  213. *R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
  214.     IO_FIELD(R_MMU_KBASE_HI, base_e, 0x8 ) |
  215.     IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
  216.     IO_FIELD(R_MMU_KBASE_HI, base_c, 0x4 ) |
  217.     IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
  218.     IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
  219.     IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
  220.     IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
  221. *R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
  222.     IO_FIELD(R_MMU_KBASE_LO, base_6, 0x0 ) |
  223.     IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) |
  224.     IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) |
  225.     IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) |
  226.     IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) |
  227.     IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) |
  228.     IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) );
  229. #else
  230. /* Etrax-100 LX version 1 has a bug so that we cannot map anything
  231.  * across the 0x80000000 boundary, so we need to shrink the user-virtual
  232.  * area to 0x50000000 instead of 0xb0000000 and map things slightly
  233.  * different. The unused areas are marked as paged so that we can catch
  234.  * freak kernel accesses there.
  235.  *
  236.  * The ARTPEC chip is mapped at 0xa so we pass that segment straight
  237.  * through. We cannot vremap it because the vmalloc area is below 0x8
  238.  * and Juliette needs an uncached area above 0x8.
  239.  *
  240.  * Same thing with 0xc and 0x9, which is memory-mapped I/O on some boards.
  241.  * We map them straight over in LOW_MAP, but use vremap in LX version 2.
  242.  */
  243. *R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, page ) | 
  244. IO_STATE(R_MMU_KSEG, seg_e, page ) |
  245. IO_STATE(R_MMU_KSEG, seg_d, page ) | 
  246. IO_STATE(R_MMU_KSEG, seg_c, page ) |   
  247. IO_STATE(R_MMU_KSEG, seg_b, seg  ) |  /* kernel reg area */
  248. #ifdef CONFIG_JULIETTE
  249. IO_STATE(R_MMU_KSEG, seg_a, seg  ) |  /* ARTPEC etc. */
  250. #else
  251. IO_STATE(R_MMU_KSEG, seg_a, page ) |
  252. #endif
  253. IO_STATE(R_MMU_KSEG, seg_9, seg  ) |  /* LED's on some boards */
  254. IO_STATE(R_MMU_KSEG, seg_8, seg  ) |  /* CSE0/1, flash and I/O */
  255. IO_STATE(R_MMU_KSEG, seg_7, page ) |  /* kernel vmalloc area */
  256. IO_STATE(R_MMU_KSEG, seg_6, seg  ) |  /* kernel DRAM area */
  257. IO_STATE(R_MMU_KSEG, seg_5, seg  ) |  /* cached flash */
  258. IO_STATE(R_MMU_KSEG, seg_4, page ) |  /* user area */
  259. IO_STATE(R_MMU_KSEG, seg_3, page ) |  /* user area */
  260. IO_STATE(R_MMU_KSEG, seg_2, page ) |  /* user area */
  261. IO_STATE(R_MMU_KSEG, seg_1, page ) |  /* user area */
  262. IO_STATE(R_MMU_KSEG, seg_0, page ) ); /* user area */
  263. *R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
  264.     IO_FIELD(R_MMU_KBASE_HI, base_e, 0x0 ) |
  265.     IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
  266.     IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
  267.     IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
  268. #ifdef CONFIG_JULIETTE
  269.     IO_FIELD(R_MMU_KBASE_HI, base_a, 0xa ) |
  270. #else
  271.     IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
  272. #endif
  273.     IO_FIELD(R_MMU_KBASE_HI, base_9, 0x9 ) |
  274.     IO_FIELD(R_MMU_KBASE_HI, base_8, 0x8 ) );
  275. *R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
  276.     IO_FIELD(R_MMU_KBASE_LO, base_6, 0x4 ) |
  277.     IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) |
  278.     IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) |
  279.     IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) |
  280.     IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) |
  281.     IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) |
  282.     IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) );
  283. #endif
  284. *R_MMU_CONTEXT = ( IO_FIELD(R_MMU_CONTEXT, page_id, 0 ) );
  285. /* The MMU has been enabled ever since head.S but just to make
  286.  * it totally obvious we do it here as well.
  287.  */
  288. *R_MMU_CTRL = ( IO_STATE(R_MMU_CTRL, inv_excp, enable ) |
  289. IO_STATE(R_MMU_CTRL, acc_excp, enable ) |
  290. IO_STATE(R_MMU_CTRL, we_excp,  enable ) );
  291. *R_MMU_ENABLE = IO_STATE(R_MMU_ENABLE, mmu_enable, enable);
  292. /*
  293.  * initialize the bad page table and bad page to point
  294.  * to a couple of allocated pages
  295.  */
  296. empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
  297. memset((void *)empty_zero_page, 0, PAGE_SIZE);
  298. /* All pages are DMA'able in Etrax, so put all in the DMA'able zone */
  299. zones_size[0] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
  300. for (i = 1; i < MAX_NR_ZONES; i++)
  301. zones_size[i] = 0;
  302. /* Use free_area_init_node instead of free_area_init, because the former
  303.  * is designed for systems where the DRAM starts at an address substantially
  304.  * higher than 0, like us (we start at PAGE_OFFSET). This saves space in the
  305.  * mem_map page array.
  306.  */
  307. free_area_init_node(0, 0, 0, zones_size, PAGE_OFFSET, 0);
  308. }
  309. extern unsigned long loops_per_jiffy; /* init/main.c */
  310. unsigned long loops_per_usec;
  311. extern char _stext, _edata, _etext;
  312. extern char __init_begin, __init_end;
  313. void __init
  314. mem_init(void)
  315. {
  316. int codesize, reservedpages, datasize, initsize;
  317. unsigned long tmp;
  318. if(!mem_map)
  319. BUG();
  320. /* max/min_low_pfn was set by setup.c
  321.  * now we just copy it to some other necessary places...
  322.  *
  323.  * high_memory was also set in setup.c
  324.  */
  325. max_mapnr = num_physpages = max_low_pfn - min_low_pfn;
  326.  
  327. /* this will put all memory onto the freelists */
  328.         totalram_pages = free_all_bootmem();
  329. reservedpages = 0;
  330. for (tmp = 0; tmp < max_mapnr; tmp++) {
  331. /*
  332.                  * Only count reserved RAM pages
  333.                  */
  334. if (PageReserved(mem_map + tmp))
  335. reservedpages++;
  336. }
  337. codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
  338.         datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
  339.         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
  340.         printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, "
  341.        "%dk init)n" ,
  342.        (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
  343.        max_mapnr << (PAGE_SHIFT-10),
  344.        codesize >> 10,
  345.        reservedpages << (PAGE_SHIFT-10),
  346.        datasize >> 10,
  347.        initsize >> 10
  348.                );
  349. /* HACK alert - calculate a loops_per_usec for asm/delay.h here
  350.  * since this is called just after calibrate_delay in init/main.c
  351.  * but before places which use udelay. cannot be in time.c since
  352.  * that is called _before_ calibrate_delay
  353.  */
  354. loops_per_usec = (loops_per_jiffy * HZ) / 1000000;
  355. return;
  356. }
  357. /* Initialize remaps of some I/O-ports. This is designed to be callable
  358.  * multiple times from the drivers init-sections, because we don't know
  359.  * beforehand which driver will get initialized first.
  360.  */
  361. void 
  362. init_ioremap(void)
  363. {
  364.   
  365. /* Give the external I/O-port addresses their values */
  366.         static int initialized = 0;
  367.   
  368.         if( !initialized ) {
  369.                 initialized++;
  370.             
  371. #ifdef CONFIG_CRIS_LOW_MAP
  372.                /* Simply a linear map (see the KSEG map above in paging_init) */
  373.                port_cse1_addr = (volatile unsigned long *)(MEM_CSE1_START | 
  374.                                                            MEM_NON_CACHEABLE);
  375.                port_csp0_addr = (volatile unsigned long *)(MEM_CSP0_START |
  376.                                                            MEM_NON_CACHEABLE);
  377.                port_csp4_addr = (volatile unsigned long *)(MEM_CSP4_START |
  378.                                                            MEM_NON_CACHEABLE);
  379. #else
  380.                /* Note that nothing blows up just because we do this remapping 
  381.                 * it's ok even if the ports are not used or connected 
  382.                 * to anything (or connected to a non-I/O thing) */        
  383.                port_cse1_addr = (volatile unsigned long *)
  384.                  ioremap((unsigned long)(MEM_CSE1_START | 
  385.                                          MEM_NON_CACHEABLE), 16);
  386.                port_csp0_addr = (volatile unsigned long *)
  387.                  ioremap((unsigned long)(MEM_CSP0_START |
  388.                                          MEM_NON_CACHEABLE), 16);
  389.                port_csp4_addr = (volatile unsigned long *)
  390.                  ioremap((unsigned long)(MEM_CSP4_START |
  391.                                          MEM_NON_CACHEABLE), 16);
  392. #endif
  393.         }
  394. }
  395. /* free the pages occupied by initialization code */
  396. void 
  397. free_initmem(void)
  398. {
  399.         unsigned long addr;
  400.         addr = (unsigned long)(&__init_begin);
  401.         for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
  402.                 ClearPageReserved(virt_to_page(addr));
  403.                 set_page_count(virt_to_page(addr), 1);
  404.                 free_page(addr);
  405.                 totalram_pages++;
  406.         }
  407.         printk ("Freeing unused kernel memory: %luk freedn", 
  408. (&__init_end - &__init_begin) >> 10);
  409. }
  410. void 
  411. si_meminfo(struct sysinfo *val)
  412. {
  413.         val->totalram = totalram_pages;
  414.         val->sharedram = 0;
  415.         val->freeram = nr_free_pages();
  416.         val->bufferram = atomic_read(&buffermem_pages);
  417.         val->totalhigh = 0;
  418.         val->freehigh = 0;
  419.         val->mem_unit = PAGE_SIZE;
  420. }