summaryrefslogtreecommitdiffstats
path: root/arch/i386/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
commitf969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch)
treeb3530d803df59d726afaabebc6626987dee1ca05 /arch/i386/mm
parenta10ce7ef2066b455d69187643ddf2073bfc4db24 (diff)
Merge with 2.3.27.
Diffstat (limited to 'arch/i386/mm')
-rw-r--r--arch/i386/mm/init.c124
1 files changed, 79 insertions, 45 deletions
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index d2089fbd0..7a05654d8 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -171,9 +171,11 @@ int do_check_pgt_cache(int low, int high)
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 @@ void set_fixmap (enum fixed_addresses idx, unsigned long phys)
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 @@ static void __init pagetable_init(void)
* 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
/*
@@ -379,10 +403,17 @@ void __init zap_low_mappings (void)
{
int i;
/*
- * Zap initial low-memory mappings:
+ * Zap initial low-memory mappings.
+ *
+ * Note that "pgd_clear()" doesn't do it for
+ * us in this case, because pgd_clear() is a
+ * no-op in the 2-level case (pmd_clear() is
+ * the thing that clears the page-tables in
+ * that case).
*/
for (i = 0; i < USER_PTRS_PER_PGD; i++)
- pgd_clear(swapper_pg_dir + i);
+ pgd_val(swapper_pg_dir[i]) = 0;
+ flush_tlb_all();
}
/*
@@ -414,13 +445,18 @@ void __init paging_init(void)
#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;
}
@@ -435,7 +471,6 @@ void __init test_wp_bit(void)
/*
* 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;
@@ -472,7 +507,6 @@ void __init test_wp_bit(void)
#endif
} else
printk(".\n");
-//#endif
}
static inline int page_is_ram (unsigned long pagenr)
@@ -535,7 +569,7 @@ void __init mem_init(void)
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),
@@ -566,7 +600,7 @@ void __init mem_init(void)
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));
@@ -581,10 +615,10 @@ void si_meminfo(struct sysinfo *val)
{
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;
}