patch-2.3.27 linux/arch/i386/mm/init.c

Next file: linux/arch/m68k/kernel/m68k_ksyms.c
Previous file: linux/arch/i386/kernel/setup.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.26/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
@@ -171,9 +171,11 @@
 	return freed;
 }
 
-/* NOTE: fixmap_init alloc all the fixmap pagetables contigous on the
-   physical space so we can cache the place of the first one and move
-   around without checking the pgd every time. */
+/*
+ * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
+ * physical space so we can cache the place of the first one and move
+ * around without checking the pgd every time.
+ */
 
 #if CONFIG_HIGHMEM
 pte_t *kmap_pte;
@@ -268,6 +270,44 @@
 	set_pte_phys (address,phys);
 }
 
+static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i, j;
+
+	i = __pgd_offset(start);
+	j = __pmd_offset(start);
+	pgd = pgd_base + i;
+
+	for ( ; (i < PTRS_PER_PGD) && (start != end); pgd++, i++) {
+#if CONFIG_X86_PAE
+		if (pgd_none(*pgd)) {
+			pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+			memset((void*)pmd, 0, PAGE_SIZE);
+			pgd_val(*pgd) = __pa(pmd) + 0x1;
+			if (pmd != pmd_offset(pgd, start))
+				BUG();
+		}
+		pmd = pmd_offset(pgd, start);
+#else
+		pmd = (pmd_t *)pgd;
+#endif
+		for (; (j < PTRS_PER_PMD) && start; pmd++, j++) {
+			if (pmd_none(*pmd)) {
+				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+				memset((void*)pte, 0, PAGE_SIZE);
+				pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+				if (pte != pte_offset(pmd, 0))
+					BUG();
+			}
+			start += PMD_SIZE;
+		}
+		j = 0;
+	}
+}
+
 static void __init pagetable_init(void)
 {
 	pgd_t *pgd, *pgd_base;
@@ -331,37 +371,21 @@
 	 * Fixed mappings, only the page table structure has to be
 	 * created - mappings will be set by set_fixmap():
 	 */
-
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-	i = __pgd_offset(vaddr);
-	j = __pmd_offset(vaddr);
-	pgd = pgd_base + i;
+	fixrange_init(vaddr, 0, pgd_base);
 
-	for ( ; (i < PTRS_PER_PGD) && vaddr; pgd++, i++) {
-#if CONFIG_X86_PAE
-		if (pgd_none(*pgd)) {
-			pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-			memset((void*)pmd, 0, PAGE_SIZE);
-			pgd_val(*pgd) = __pa(pmd) + 0x1;
-			if (pmd != pmd_offset(pgd, vaddr))
-				BUG();
-		}
-		pmd = pmd_offset(pgd, vaddr);
-#else
-		pmd = (pmd_t *)pgd;
+#if CONFIG_HIGHMEM
+	/*
+	 * Permanent kmaps:
+	 */
+	vaddr = PKMAP_BASE;
+	fixrange_init(vaddr, vaddr + 4*1024*1024, pgd_base);
+
+	pgd = swapper_pg_dir + __pgd_offset(vaddr);
+	pmd = pmd_offset(pgd, vaddr);
+	pte = pte_offset(pmd, vaddr);
+	pkmap_page_table = pte;
 #endif
-		for (; (j < PTRS_PER_PMD) && vaddr; pmd++, j++) {
-			if (pmd_none(*pmd)) {
-				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-				memset((void*)pte, 0, PAGE_SIZE);
-				pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
-				if (pte != pte_offset(pmd, 0))
-					BUG();
-			}
-			vaddr += PMD_SIZE;
-		}
-		j = 0;
-	}
 
 #if CONFIG_X86_PAE
 	/*
@@ -389,6 +413,7 @@
 	 */
 	for (i = 0; i < USER_PTRS_PER_PGD; i++)
 		pgd_val(swapper_pg_dir[i]) = 0;
+	flush_tlb_all();
 }
 
 /*
@@ -420,13 +445,18 @@
 #endif
 
 #ifdef CONFIG_HIGHMEM
-	kmap_init(); /* run after fixmap_init */
-#endif
-#ifdef CONFIG_HIGHMEM
-	free_area_init(highend_pfn);
-#else
-	free_area_init(max_low_pfn);
+	kmap_init();
 #endif
+	{
+		unsigned int zones_size[3];
+
+		zones_size[0] = virt_to_phys((char *)MAX_DMA_ADDRESS)
+					 >> PAGE_SHIFT;
+		zones_size[1] = max_low_pfn - zones_size[0];
+		zones_size[2] = highend_pfn - zones_size[0] - zones_size[1];
+
+		free_area_init(zones_size);
+	}
 	return;
 }
 
@@ -441,7 +471,6 @@
 /*
  * Ok, all PAE-capable CPUs are definitely handling the WP bit right.
  */
-//#ifndef CONFIG_X86_PAE
 	const unsigned long vaddr = PAGE_OFFSET;
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -478,7 +507,6 @@
 #endif
 	} else
 		printk(".\n");
-//#endif
 }
 
 static inline int page_is_ram (unsigned long pagenr)
@@ -541,7 +569,7 @@
 	totalram_pages += totalhigh_pages;
 #endif
 	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
-		(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 		max_mapnr << (PAGE_SHIFT-10),
 		codepages << (PAGE_SHIFT-10),
 		reservedpages << (PAGE_SHIFT-10),
@@ -572,7 +600,7 @@
 void free_initmem(void)
 {
 	unsigned long addr;
-	
+
 	addr = (unsigned long)(&__init_begin);
 	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
 		ClearPageReserved(mem_map + MAP_NR(addr));
@@ -587,10 +615,10 @@
 {
 	val->totalram = totalram_pages;
 	val->sharedram = 0;
-	val->freeram = nr_free_pages;
+	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = totalhigh_pages;
-	val->freehigh = nr_free_highpages;
+	val->freehigh = nr_free_highpages();
 	val->mem_unit = PAGE_SIZE;
 	return;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)