11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public
31da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive
41da177e4SLinus Torvalds * for more details.
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * Copyright (C) 2003 by Ralf Baechle
71da177e4SLinus Torvalds */
81da177e4SLinus Torvalds #include <linux/init.h>
91da177e4SLinus Torvalds #include <linux/mm.h>
1057c8a661SMike Rapoport #include <linux/memblock.h>
111da177e4SLinus Torvalds #include <linux/highmem.h>
1284fd089aSRalf Baechle #include <asm/fixmap.h>
136a1e5529SAtsushi Nemoto #include <asm/pgalloc.h>
1435476311SDaniel Silsby #include <asm/tlbflush.h>
151da177e4SLinus Torvalds
pgd_init(void * addr)1622c4e804SFeiyang Chen void pgd_init(void *addr)
171da177e4SLinus Torvalds {
1822c4e804SFeiyang Chen unsigned long *p = (unsigned long *)addr;
191da177e4SLinus Torvalds int i;
201da177e4SLinus Torvalds
211da177e4SLinus Torvalds for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
221da177e4SLinus Torvalds p[i + 0] = (unsigned long) invalid_pte_table;
231da177e4SLinus Torvalds p[i + 1] = (unsigned long) invalid_pte_table;
241da177e4SLinus Torvalds p[i + 2] = (unsigned long) invalid_pte_table;
251da177e4SLinus Torvalds p[i + 3] = (unsigned long) invalid_pte_table;
261da177e4SLinus Torvalds p[i + 4] = (unsigned long) invalid_pte_table;
271da177e4SLinus Torvalds p[i + 5] = (unsigned long) invalid_pte_table;
281da177e4SLinus Torvalds p[i + 6] = (unsigned long) invalid_pte_table;
291da177e4SLinus Torvalds p[i + 7] = (unsigned long) invalid_pte_table;
301da177e4SLinus Torvalds }
311da177e4SLinus Torvalds }
321da177e4SLinus Torvalds
3335476311SDaniel Silsby #if defined(CONFIG_TRANSPARENT_HUGEPAGE)
mk_pmd(struct page * page,pgprot_t prot)3435476311SDaniel Silsby pmd_t mk_pmd(struct page *page, pgprot_t prot)
3535476311SDaniel Silsby {
3635476311SDaniel Silsby pmd_t pmd;
3735476311SDaniel Silsby
38*15fa3e8eSMatthew Wilcox (Oracle) pmd_val(pmd) = (page_to_pfn(page) << PFN_PTE_SHIFT) | pgprot_val(prot);
3935476311SDaniel Silsby
4035476311SDaniel Silsby return pmd;
4135476311SDaniel Silsby }
4235476311SDaniel Silsby
4335476311SDaniel Silsby
set_pmd_at(struct mm_struct * mm,unsigned long addr,pmd_t * pmdp,pmd_t pmd)4435476311SDaniel Silsby void set_pmd_at(struct mm_struct *mm, unsigned long addr,
4535476311SDaniel Silsby pmd_t *pmdp, pmd_t pmd)
4635476311SDaniel Silsby {
4735476311SDaniel Silsby *pmdp = pmd;
4835476311SDaniel Silsby }
4935476311SDaniel Silsby #endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */
5035476311SDaniel Silsby
pagetable_init(void)511da177e4SLinus Torvalds void __init pagetable_init(void)
521da177e4SLinus Torvalds {
531da177e4SLinus Torvalds unsigned long vaddr;
54f8829caeSRalf Baechle pgd_t *pgd_base;
55f8829caeSRalf Baechle #ifdef CONFIG_HIGHMEM
56f8829caeSRalf Baechle pgd_t *pgd;
572bee1b58SMike Rapoport p4d_t *p4d;
58c6e8b587SRalf Baechle pud_t *pud;
591da177e4SLinus Torvalds pmd_t *pmd;
601da177e4SLinus Torvalds pte_t *pte;
611da177e4SLinus Torvalds #endif
621da177e4SLinus Torvalds
631da177e4SLinus Torvalds /* Initialize the entire pgd. */
6422c4e804SFeiyang Chen pgd_init(swapper_pg_dir);
6522c4e804SFeiyang Chen pgd_init(&swapper_pg_dir[USER_PTRS_PER_PGD]);
661da177e4SLinus Torvalds
671da177e4SLinus Torvalds pgd_base = swapper_pg_dir;
681da177e4SLinus Torvalds
691da177e4SLinus Torvalds /*
701da177e4SLinus Torvalds * Fixed mappings:
711da177e4SLinus Torvalds */
7271eb989aSMarcin Nowakowski vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
7371eb989aSMarcin Nowakowski fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base);
741da177e4SLinus Torvalds
75f8829caeSRalf Baechle #ifdef CONFIG_HIGHMEM
761da177e4SLinus Torvalds /*
771da177e4SLinus Torvalds * Permanent kmaps:
781da177e4SLinus Torvalds */
791da177e4SLinus Torvalds vaddr = PKMAP_BASE;
8071eb989aSMarcin Nowakowski fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
811da177e4SLinus Torvalds
8231168f03SMike Rapoport pgd = swapper_pg_dir + pgd_index(vaddr);
832bee1b58SMike Rapoport p4d = p4d_offset(pgd, vaddr);
842bee1b58SMike Rapoport pud = pud_offset(p4d, vaddr);
85c6e8b587SRalf Baechle pmd = pmd_offset(pud, vaddr);
861da177e4SLinus Torvalds pte = pte_offset_kernel(pmd, vaddr);
871da177e4SLinus Torvalds pkmap_page_table = pte;
881da177e4SLinus Torvalds #endif
891da177e4SLinus Torvalds }
90