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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  
  3.  *
  4.  *  PowerPC version 
  5.  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  6.  *
  7.  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  8.  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  9.  *    Copyright (C) 1996 Paul Mackerras
  10.  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  11.  *
  12.  *  Derived from "arch/i386/mm/init.c"
  13.  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  14.  *
  15.  *  Dave Engebretsen <engebret@us.ibm.com>
  16.  *      Rework for PPC64 port.
  17.  *
  18.  *  This program is free software; you can redistribute it and/or
  19.  *  modify it under the terms of the GNU General Public License
  20.  *  as published by the Free Software Foundation; either version
  21.  *  2 of the License, or (at your option) any later version.
  22.  *
  23.  */
  24. #include <linux/config.h>
  25. #include <linux/signal.h>
  26. #include <linux/sched.h>
  27. #include <linux/kernel.h>
  28. #include <linux/errno.h>
  29. #include <linux/string.h>
  30. #include <linux/types.h>
  31. #include <linux/ptrace.h>
  32. #include <linux/mman.h>
  33. #include <linux/mm.h>
  34. #include <linux/swap.h>
  35. #include <linux/stddef.h>
  36. #include <linux/vmalloc.h>
  37. #include <linux/init.h>
  38. #include <linux/delay.h>
  39. #include <linux/bootmem.h>
  40. #ifdef CONFIG_BLK_DEV_INITRD
  41. #include <linux/blk.h> /* for initrd_* */
  42. #endif
  43. #include <asm/pgalloc.h>
  44. #include <asm/page.h>
  45. #include <asm/abs_addr.h>
  46. #include <asm/prom.h>
  47. #include <asm/lmb.h>
  48. #include <asm/rtas.h>
  49. #include <asm/io.h>
  50. #include <asm/mmu_context.h>
  51. #include <asm/pgtable.h>
  52. #include <asm/mmu.h>
  53. #include <asm/uaccess.h>
  54. #include <asm/smp.h>
  55. #include <asm/machdep.h>
  56. #include <asm/tlb.h>
  57. #include <asm/Naca.h>
  58. #include <asm/ppcdebug.h>
  59. #define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
  60. #ifdef CONFIG_PPC_ISERIES
  61. #include <asm/iSeries/iSeries_dma.h>
  62. #endif
  63. struct mmu_context_stack_t mmu_context_stack;
  64. int mem_init_done;
  65. unsigned long ioremap_bot = IMALLOC_BASE;
  66. static int boot_mapsize;
  67. static unsigned long totalram_pages;
  68. static struct device_node *memory_node;
  69. extern pgd_t swapper_pg_dir[];
  70. extern char __init_begin, __init_end;
  71. extern char __chrp_begin, __chrp_end;
  72. extern char __openfirmware_begin, __openfirmware_end;
  73. extern struct _of_tce_table of_tce_table[];
  74. extern char _start[], _end[];
  75. extern char _stext[], etext[];
  76. extern struct task_struct *current_set[NR_CPUS];
  77. extern struct Naca *naca;
  78. void mm_init_ppc64(void);
  79. void make_pte(HPTE * htab,
  80.               unsigned long va, unsigned long pa, 
  81.               int mode, unsigned long hash_mask);
  82. unsigned long *pmac_find_end_of_memory(void);
  83. extern unsigned long *find_end_of_memory(void);
  84. extern pgd_t ioremap_dir[];
  85. extern pgd_t bolted_dir[];
  86. pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir;
  87. pgd_t * bolted_pgd  = (pgd_t *)&bolted_dir;
  88. static void map_io_page(unsigned long va, unsigned long pa, int flags);
  89. extern void die_if_kernel(char *,struct pt_regs *,long);
  90. unsigned long klimit = (unsigned long)_end;
  91. HPTE *Hash=0;
  92. unsigned long Hash_size=0;
  93. unsigned long _SDR1=0;
  94. unsigned long _ASR=0;
  95. /* max amount of RAM to use */
  96. unsigned long __max_memory;
  97. /* This is declared as we are using the more or less generic 
  98.  * include/asm-ppc64/tlb.h file -- tgall
  99.  */
  100. mmu_gather_t     mmu_gathers[NR_CPUS];
  101. int do_check_pgt_cache(int low, int high)
  102. {
  103. int freed = 0;
  104. if (pgtable_cache_size > high) {
  105. do {
  106. if (pgd_quicklist)
  107. free_page((unsigned long)pgd_alloc_one_fast(0)), ++freed;
  108. if (pmd_quicklist)
  109. free_page((unsigned long)pmd_alloc_one_fast(0, 0)), ++freed;
  110. if (pte_quicklist)
  111. free_page((unsigned long)pte_alloc_one_fast(0, 0)), ++freed;
  112. } while (pgtable_cache_size > low);
  113. }
  114. return freed;
  115. }
  116. void show_mem(void)
  117. {
  118. int i,free = 0,total = 0,reserved = 0;
  119. int shared = 0, cached = 0;
  120. struct task_struct *p;
  121. printk("Mem-info:n");
  122. show_free_areas();
  123. printk("Free swap:       %6dkBn",nr_swap_pages<<(PAGE_SHIFT-10));
  124. i = max_mapnr;
  125. while (i-- > 0) {
  126. total++;
  127. if (PageReserved(mem_map+i))
  128. reserved++;
  129. else if (PageSwapCache(mem_map+i))
  130. cached++;
  131. else if (!atomic_read(&mem_map[i].count))
  132. free++;
  133. else
  134. shared += atomic_read(&mem_map[i].count) - 1;
  135. }
  136. printk("%d pages of RAMn",total);
  137. printk("%d free pagesn",free);
  138. printk("%d reserved pagesn",reserved);
  139. printk("%d pages sharedn",shared);
  140. printk("%d pages swap cachedn",cached);
  141. printk("%d pages in page table cachen",(int)pgtable_cache_size);
  142. show_buffers();
  143. printk("%-8s %3s %8s %8s %8s %9s %8s", "Process", "Pid",
  144.        "Ctx", "Ctx<<4", "Last Sys", "pc", "task");
  145. #ifdef CONFIG_SMP
  146. printk(" %3s", "CPU");
  147. #endif /* CONFIG_SMP */
  148. printk("n");
  149. for_each_task(p)
  150. {
  151. printk("%-8.8s %3d %8ld %8ld %8ld %c%08lx %08lx ",
  152.        p->comm,p->pid,
  153.        (p->mm)?p->mm->context:0,
  154.        (p->mm)?(p->mm->context<<4):0,
  155.        p->thread.last_syscall,
  156.        (p->thread.regs)?user_mode(p->thread.regs) ? 'u' : 'k' : '?',
  157.        (p->thread.regs)?p->thread.regs->nip:0,
  158.        (ulong)p);
  159. {
  160. int iscur = 0;
  161. #ifdef CONFIG_SMP
  162. printk("%3d ", p->processor);
  163. if ( (p->processor != NO_PROC_ID) &&
  164.      (p == current_set[p->processor]) )
  165. {
  166. iscur = 1;
  167. printk("current");
  168. }
  169. #else
  170. if ( p == current )
  171. {
  172. iscur = 1;
  173. printk("current");
  174. }
  175. if ( p == last_task_used_math )
  176. {
  177. if ( iscur )
  178. printk(",");
  179. printk("last math");
  180. }
  181. #endif /* CONFIG_SMP */
  182. printk("n");
  183. }
  184. }
  185. }
  186. void si_meminfo(struct sysinfo *val)
  187. {
  188.   val->totalram = totalram_pages;
  189. val->sharedram = 0;
  190. val->freeram = nr_free_pages();
  191. val->bufferram = atomic_read(&buffermem_pages);
  192. val->totalhigh = 0;
  193. val->freehigh = 0;
  194. val->mem_unit = PAGE_SIZE;
  195. }
  196. void *
  197. ioremap(unsigned long addr, unsigned long size)
  198. {
  199. return __ioremap(addr, size, _PAGE_NO_CACHE);
  200. }
  201. extern struct vm_struct * get_im_area( unsigned long size );
  202. void *
  203. __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
  204. {
  205. unsigned long pa, ea, i;
  206. /*
  207.  * Choose an address to map it to.
  208.  * Once the imalloc system is running, we use it.
  209.  * Before that, we map using addresses going
  210.  * up from ioremap_bot.  imalloc will use
  211.  * the addresses from ioremap_bot through
  212.  * IMALLOC_END (0xE000001fffffffff)
  213.  * 
  214.  */
  215. pa = addr & PAGE_MASK;
  216. size = PAGE_ALIGN(addr + size) - pa;
  217. // MIKEC: Do we still need to support this?
  218. /*
  219.  * If the address lies within the first 16 MB, assume it's in ISA
  220.  * memory space
  221.  */
  222. if (pa < 16*1024*1024)
  223.     pa += _ISA_MEM_BASE;
  224. /*
  225.  * Don't allow anybody to remap normal RAM that we're using.
  226.  * mem_init() sets high_memory so only do the check after that.
  227.  */
  228. #if 0  /* DRENG / PPPBBB assert to not remap DRAM is not right when I/O
  229.         * space is in the middle of DRAM ranges ...
  230. */
  231. if ( mem_init_done && (pa < virt_to_phys(high_memory)) )
  232. {
  233. printk("__ioremap(): phys addr %0lx is RAM lr %pn", pa,
  234.        __builtin_return_address(0));
  235. return NULL;
  236. }
  237. #endif
  238. if (size == 0)
  239. return NULL;
  240. if (mem_init_done) {
  241. struct vm_struct *area;
  242. area = get_im_area(size);
  243. if (area == 0)
  244. return NULL;
  245. ea = (unsigned long)(area->addr);
  246. else {
  247. ea = ioremap_bot;
  248. ioremap_bot += size;
  249.         }
  250. if ((flags & _PAGE_PRESENT) == 0)
  251. flags |= pgprot_val(PAGE_KERNEL);
  252. if (flags & (_PAGE_NO_CACHE | _PAGE_WRITETHRU))
  253. flags |= _PAGE_GUARDED;
  254. for (i = 0; i < size; i += PAGE_SIZE) {
  255. map_io_page(ea+i, pa+i, flags);
  256. }
  257. return (void *) (ea + (addr & ~PAGE_MASK));
  258. }
  259. void iounmap(void *addr)
  260. {
  261. /* DRENG / PPPBBB todo */
  262. }
  263. unsigned long iopa(unsigned long addr)
  264. {
  265. pmd_t *pd;
  266. pte_t *pg;
  267. /* Do we have a page table? */
  268. if (init_mm.pgd == NULL)
  269. return 0;
  270. /* Use upper 10 bits of addr to index the first level map */
  271. pd = (pmd_t *) (init_mm.pgd + (addr >> PGDIR_SHIFT));
  272. if (pmd_none(*pd))
  273. return 0;
  274. /* Use middle 10 bits of addr to index the second-level map */
  275. pg = pte_offset(pd, addr);
  276. return (pte_val(*pg) & PAGE_MASK) | (addr & ~PAGE_MASK);
  277. }
  278. /*
  279.  * map_io_page currently only called by __ioremap
  280.  * map_io_page adds an entry to the ioremap page table
  281.  * and adds an entry to the HPT, possibly bolting it
  282.  */
  283. static void map_io_page(unsigned long ea, unsigned long pa, int flags)
  284. {
  285. pgd_t *pgdp;
  286. pmd_t *pmdp;
  287. pte_t *ptep;
  288. unsigned long vsid;
  289. if (mem_init_done) {
  290. spin_lock(&init_mm.page_table_lock);
  291. pgdp = pgd_offset_i(ea);
  292. pmdp = pmd_alloc(&init_mm, pgdp, ea);
  293. ptep = pte_alloc(&init_mm, pmdp, ea);
  294. set_pte(ptep, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
  295. spin_unlock(&init_mm.page_table_lock);
  296. } else {
  297. /* If the mm subsystem is not fully up, we cannot create a
  298.  * linux page table entry for this mapping.  Simply bolt an
  299.  * entry in the hardware page table. 
  300.    */
  301. vsid = get_kernel_vsid(ea);
  302. make_pte(htab_data.htab,
  303. (vsid << 28) | (ea & 0xFFFFFFF), // va (NOT the ea)
  304. pa, 
  305. _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX,
  306. htab_data.htab_hash_mask); 
  307. }
  308. }
  309. void
  310. local_flush_tlb_all(void)
  311. {
  312. /* Implemented to just flush the vmalloc area.
  313.  * vmalloc is the only user of flush_tlb_all.
  314.  */
  315. local_flush_tlb_range( NULL, VMALLOC_START, VMALLOC_END );
  316. }
  317. void
  318. local_flush_tlb_mm(struct mm_struct *mm)
  319. {
  320. if ( mm->map_count ) {
  321. struct vm_area_struct *mp;
  322. for ( mp = mm->mmap; mp != NULL; mp = mp->vm_next )
  323. local_flush_tlb_range( mm, mp->vm_start, mp->vm_end );
  324. }
  325. else /* MIKEC: It is not clear why this is needed */
  326. local_flush_tlb_range( mm, USER_START, USER_END );
  327. }
  328. /*
  329.  * Callers should hold the mm->page_table_lock
  330.  */
  331. void
  332. local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
  333. {
  334. unsigned long context = 0;
  335. pgd_t *pgd;
  336. pmd_t *pmd;
  337. pte_t *ptep;
  338. pte_t pte;
  339. switch( REGION_ID(vmaddr) ) {
  340. case VMALLOC_REGION_ID:
  341. pgd = pgd_offset_k( vmaddr );
  342. break;
  343. case IO_REGION_ID:
  344. pgd = pgd_offset_i( vmaddr );
  345. break;
  346. case BOLTED_REGION_ID:
  347. pgd = pgd_offset_b( vmaddr );
  348. break;
  349. case USER_REGION_ID:
  350. pgd = pgd_offset( vma->vm_mm, vmaddr );
  351. context = vma->vm_mm->context;
  352. break;
  353. default:
  354. panic("local_flush_tlb_page: invalid region 0x%016lx", vmaddr);
  355. }
  356. if (!pgd_none(*pgd)) {
  357. pmd = pmd_offset(pgd, vmaddr);
  358. if (!pmd_none(*pmd)) {
  359. ptep = pte_offset(pmd, vmaddr);
  360. /* Check if HPTE might exist and flush it if so */
  361. pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
  362. if ( pte_val(pte) & _PAGE_HASHPTE ) {
  363. flush_hash_page(context, vmaddr, pte);
  364. }
  365. }
  366. }
  367. }
  368. void
  369. local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
  370. {
  371. pgd_t *pgd;
  372. pmd_t *pmd;
  373. pte_t *ptep;
  374. pte_t pte;
  375. unsigned long pgd_end, pmd_end;
  376. unsigned long context;
  377. if ( start >= end )
  378. panic("flush_tlb_range: start (%016lx) greater than end (%016lx)n", start, end );
  379. if ( REGION_ID(start) != REGION_ID(end) )
  380. panic("flush_tlb_range: start (%016lx) and end (%016lx) not in same regionn", start, end );
  381. context = 0;
  382. switch( REGION_ID(start) ) {
  383. case VMALLOC_REGION_ID:
  384. pgd = pgd_offset_k( start );
  385. break;
  386. case IO_REGION_ID:
  387. pgd = pgd_offset_i( start );
  388. break;
  389. case BOLTED_REGION_ID:
  390. pgd = pgd_offset_b( start );
  391. break;
  392. case USER_REGION_ID:
  393. pgd = pgd_offset( mm, start );
  394. context = mm->context;
  395. break;
  396. default:
  397. panic("flush_tlb_range: invalid region for start (%016lx) and end (%016lx)n", start, end);
  398. }
  399. do {
  400. pgd_end = (start + PGDIR_SIZE) & PGDIR_MASK;
  401. if ( pgd_end > end ) 
  402. pgd_end = end;
  403. if ( !pgd_none( *pgd ) ) {
  404. pmd = pmd_offset( pgd, start );
  405. do {
  406. pmd_end = ( start + PMD_SIZE ) & PMD_MASK;
  407. if ( pmd_end > end )
  408. pmd_end = end;
  409. if ( !pmd_none( *pmd ) ) {
  410. ptep = pte_offset( pmd, start );
  411. do {
  412. if ( pte_val(*ptep) & _PAGE_HASHPTE ) {
  413. pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
  414. if ( pte_val(pte) & _PAGE_HASHPTE )
  415. flush_hash_page( context, start, pte );
  416. }
  417. start += PAGE_SIZE;
  418. ++ptep;
  419. } while ( start < pmd_end );
  420. }
  421. else
  422. start = pmd_end;
  423. ++pmd;
  424. } while ( start < pgd_end );
  425. }
  426. else
  427. start = pgd_end;
  428. ++pgd;
  429. } while ( start < end );
  430. }
  431. void __init free_initmem(void)
  432. {
  433. unsigned long a;
  434. unsigned long num_freed_pages = 0;
  435. #define FREESEC(START,END,CNT) do { 
  436. a = (unsigned long)(&START); 
  437. for (; a < (unsigned long)(&END); a += PAGE_SIZE) { 
  438.    clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags); 
  439. set_page_count(mem_map+MAP_NR(a), 1); 
  440. free_page(a); 
  441. CNT++; 
  442. } while (0)
  443. FREESEC(__init_begin,__init_end,num_freed_pages);
  444. printk ("Freeing unused kernel memory: %ldk initn",
  445. PGTOKB(num_freed_pages));
  446. }
  447. #ifdef CONFIG_BLK_DEV_INITRD
  448. void free_initrd_mem(unsigned long start, unsigned long end)
  449. {
  450. for (; start < end; start += PAGE_SIZE) {
  451. ClearPageReserved(mem_map + MAP_NR(start));
  452. set_page_count(mem_map+MAP_NR(start), 1);
  453. free_page(start);
  454. totalram_pages++;
  455. }
  456. printk ("Freeing initrd memory: %ldk freedn", (end - start) >> 10);
  457. }
  458. #endif
  459. /* Reserve all contexts < FIRST_USER_CONTEXT for kernel use.
  460.  * The range of contexts [FIRST_USER_CONTEXT, NUM_USER_CONTEXT)
  461.  * are stored on a stack for easy allocation and deallocation.
  462.  */
  463. void
  464. init_context_stack(void)
  465. {
  466.         mm_context_t top;
  467.         mmu_context_stack.lock = SPIN_LOCK_UNLOCKED;
  468.         mmu_context_stack.top = FIRST_USER_CONTEXT;
  469.         for(top=0; top < FIRST_USER_CONTEXT ;top++) {
  470.                 mmu_context_stack.stack[top] = NO_CONTEXT;
  471.         }
  472.         for(top=FIRST_USER_CONTEXT; top < NUM_USER_CONTEXT ;top++) {
  473.                 mmu_context_stack.stack[top] = top;
  474.         }
  475. }
  476. /*
  477.  * Do very early mm setup.
  478.  */
  479. void __init mm_init_ppc64(void) {
  480. ppc_md.progress("MM:init", 0);
  481. /* Reserve all contexts < FIRST_USER_CONTEXT for kernel use.
  482.  * The range of contexts [FIRST_USER_CONTEXT, NUM_USER_CONTEXT)
  483.  * are stored on a stack for easy allocation and deallocation.
  484.  */
  485. init_context_stack();
  486. ppc_md.progress("MM:exit", 0x211);
  487. }
  488. /*
  489.  * Initialize the bootmem system and give it all the memory we
  490.  * have available.
  491.  */
  492. void __init do_init_bootmem(void)
  493. {
  494. unsigned long i;
  495. unsigned long start, bootmap_pages;
  496. unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
  497. PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: startn");
  498. /*
  499.  * Find an area to use for the bootmem bitmap.  Calculate the size of
  500.  * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
  501.  * Add 1 additional page in case the address isn't page-aligned.
  502.  */
  503. bootmap_pages = bootmem_bootmap_pages(total_pages);
  504. start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE));
  505. if( start == 0 ) {
  506. udbg_printf("do_init_bootmem: failed to allocate a bitmap.n");
  507. udbg_printf("tbootmap_pages = 0x%lx.n", bootmap_pages);
  508. PPCDBG_ENTER_DEBUGGER(); 
  509. }
  510. PPCDBG(PPCDBG_MMINIT, "tstart               = 0x%lxn", start);
  511. PPCDBG(PPCDBG_MMINIT, "tbootmap_pages       = 0x%lxn", bootmap_pages);
  512. PPCDBG(PPCDBG_MMINIT, "tphysicalMemorySize  = 0x%lxn", naca->physicalMemorySize);
  513. boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
  514. PPCDBG(PPCDBG_MMINIT, "tboot_mapsize        = 0x%lxn", boot_mapsize);
  515. /* add all physical memory to the bootmem map */
  516. for (i=0; i < lmb.memory.cnt ;i++) {
  517. unsigned long physbase = lmb.memory.region[i].physbase;
  518. unsigned long size = lmb.memory.region[i].size;
  519. free_bootmem(physbase, size);
  520. }
  521. /* reserve the sections we're already using */
  522. for (i=0; i < lmb.reserved.cnt ;i++) {
  523. unsigned long physbase = lmb.reserved.region[i].physbase;
  524. unsigned long size = lmb.reserved.region[i].size;
  525. #if 0 /* PPPBBB */
  526. if ( (physbase == 0) && (size < (16<<20)) ) {
  527. size = 16 << 20;
  528. }
  529. #endif
  530. reserve_bootmem(physbase, size);
  531. }
  532. PPCDBG(PPCDBG_MMINIT, "do_init_bootmem: endn");
  533. }
  534. /*
  535.  * paging_init() sets up the page tables - in fact we've already done this.
  536.  */
  537. void __init paging_init(void)
  538. {
  539. unsigned long zones_size[MAX_NR_ZONES], i;
  540. /*
  541.  * All pages are DMA-able so we put them all in the DMA zone.
  542.  */
  543. zones_size[0] = lmb_end_of_DRAM() >> PAGE_SHIFT;
  544. for (i = 1; i < MAX_NR_ZONES; i++)
  545. zones_size[i] = 0;
  546. free_area_init(zones_size);
  547. }
  548. void __init mem_init(void)
  549. {
  550. extern char *sysmap; 
  551. extern unsigned long sysmap_size;
  552. unsigned long addr;
  553. int codepages = 0;
  554. int datapages = 0;
  555. int initpages = 0;
  556. unsigned long va_rtas_base = (unsigned long)__va(rtas.base);
  557. max_mapnr = max_low_pfn;
  558. high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
  559. num_physpages = max_mapnr; /* RAM is assumed contiguous */
  560. totalram_pages += free_all_bootmem();
  561. ifppcdebug(PPCDBG_MMINIT) {
  562. udbg_printf("mem_init: totalram_pages = 0x%lxn", totalram_pages);
  563. udbg_printf("mem_init: va_rtas_base   = 0x%lxn", va_rtas_base); 
  564. udbg_printf("mem_init: va_rtas_end    = 0x%lxn", PAGE_ALIGN(va_rtas_base+rtas.size)); 
  565. udbg_printf("mem_init: pinned start   = 0x%lxn", __va(0)); 
  566. udbg_printf("mem_init: pinned end     = 0x%lxn", PAGE_ALIGN(klimit)); 
  567. }
  568. if ( sysmap_size )
  569. for (addr = (unsigned long)sysmap;
  570.      addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
  571.      addr += PAGE_SIZE)
  572. SetPageReserved(mem_map + MAP_NR(addr));
  573. for (addr = KERNELBASE; addr <= (unsigned long)__va(lmb_end_of_DRAM());
  574.      addr += PAGE_SIZE) {
  575. if (!PageReserved(mem_map + MAP_NR(addr)))
  576. continue;
  577. if (addr < (ulong) etext)
  578. codepages++;
  579. else if (addr >= (unsigned long)&__init_begin
  580.  && addr < (unsigned long)&__init_end)
  581. initpages++;
  582. else if (addr < klimit)
  583. datapages++;
  584. }
  585.         printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]n",
  586.        (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
  587.        codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
  588.        initpages<< (PAGE_SHIFT-10),
  589.        PAGE_OFFSET, __va(lmb_end_of_DRAM()));
  590. mem_init_done = 1;
  591. #ifdef CONFIG_PPC_ISERIES
  592. create_virtual_bus_tce_table();
  593. #endif
  594. }