Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 2003 by Ralf Baechle
0007  */
0008 #include <linux/init.h>
0009 #include <linux/mm.h>
0010 #include <linux/memblock.h>
0011 #include <linux/highmem.h>
0012 #include <asm/fixmap.h>
0013 #include <asm/pgalloc.h>
0014 #include <asm/tlbflush.h>
0015 
0016 void pgd_init(unsigned long page)
0017 {
0018     unsigned long *p = (unsigned long *) page;
0019     int i;
0020 
0021     for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
0022         p[i + 0] = (unsigned long) invalid_pte_table;
0023         p[i + 1] = (unsigned long) invalid_pte_table;
0024         p[i + 2] = (unsigned long) invalid_pte_table;
0025         p[i + 3] = (unsigned long) invalid_pte_table;
0026         p[i + 4] = (unsigned long) invalid_pte_table;
0027         p[i + 5] = (unsigned long) invalid_pte_table;
0028         p[i + 6] = (unsigned long) invalid_pte_table;
0029         p[i + 7] = (unsigned long) invalid_pte_table;
0030     }
0031 }
0032 
0033 #if defined(CONFIG_TRANSPARENT_HUGEPAGE)
0034 pmd_t mk_pmd(struct page *page, pgprot_t prot)
0035 {
0036     pmd_t pmd;
0037 
0038     pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot);
0039 
0040     return pmd;
0041 }
0042 
0043 
0044 void set_pmd_at(struct mm_struct *mm, unsigned long addr,
0045         pmd_t *pmdp, pmd_t pmd)
0046 {
0047     *pmdp = pmd;
0048 }
0049 #endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */
0050 
0051 void __init pagetable_init(void)
0052 {
0053     unsigned long vaddr;
0054     pgd_t *pgd_base;
0055 #ifdef CONFIG_HIGHMEM
0056     pgd_t *pgd;
0057     p4d_t *p4d;
0058     pud_t *pud;
0059     pmd_t *pmd;
0060     pte_t *pte;
0061 #endif
0062 
0063     /* Initialize the entire pgd.  */
0064     pgd_init((unsigned long)swapper_pg_dir);
0065     pgd_init((unsigned long)swapper_pg_dir
0066          + sizeof(pgd_t) * USER_PTRS_PER_PGD);
0067 
0068     pgd_base = swapper_pg_dir;
0069 
0070     /*
0071      * Fixed mappings:
0072      */
0073     vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
0074     fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base);
0075 
0076 #ifdef CONFIG_HIGHMEM
0077     /*
0078      * Permanent kmaps:
0079      */
0080     vaddr = PKMAP_BASE;
0081     fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
0082 
0083     pgd = swapper_pg_dir + pgd_index(vaddr);
0084     p4d = p4d_offset(pgd, vaddr);
0085     pud = pud_offset(p4d, vaddr);
0086     pmd = pmd_offset(pud, vaddr);
0087     pte = pte_offset_kernel(pmd, vaddr);
0088     pkmap_page_table = pte;
0089 #endif
0090 }