diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
commit | f969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch) | |
tree | b3530d803df59d726afaabebc6626987dee1ca05 /arch/i386/mm/init.c | |
parent | a10ce7ef2066b455d69187643ddf2073bfc4db24 (diff) |
Merge with 2.3.27.
Diffstat (limited to 'arch/i386/mm/init.c')
-rw-r--r-- | arch/i386/mm/init.c | 124 |
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; } |