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) 1999, 2000 by Silicon Graphics
0007  * Copyright (C) 2003 by Ralf Baechle
0008  */
0009 #include <linux/export.h>
0010 #include <linux/init.h>
0011 #include <linux/mm.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, *end;
0019     unsigned long entry;
0020 
0021 #if !defined(__PAGETABLE_PUD_FOLDED)
0022     entry = (unsigned long)invalid_pud_table;
0023 #elif !defined(__PAGETABLE_PMD_FOLDED)
0024     entry = (unsigned long)invalid_pmd_table;
0025 #else
0026     entry = (unsigned long)invalid_pte_table;
0027 #endif
0028 
0029     p = (unsigned long *) page;
0030     end = p + PTRS_PER_PGD;
0031 
0032     do {
0033         p[0] = entry;
0034         p[1] = entry;
0035         p[2] = entry;
0036         p[3] = entry;
0037         p[4] = entry;
0038         p += 8;
0039         p[-3] = entry;
0040         p[-2] = entry;
0041         p[-1] = entry;
0042     } while (p != end);
0043 }
0044 
0045 #ifndef __PAGETABLE_PMD_FOLDED
0046 void pmd_init(unsigned long addr, unsigned long pagetable)
0047 {
0048     unsigned long *p, *end;
0049 
0050     p = (unsigned long *) addr;
0051     end = p + PTRS_PER_PMD;
0052 
0053     do {
0054         p[0] = pagetable;
0055         p[1] = pagetable;
0056         p[2] = pagetable;
0057         p[3] = pagetable;
0058         p[4] = pagetable;
0059         p += 8;
0060         p[-3] = pagetable;
0061         p[-2] = pagetable;
0062         p[-1] = pagetable;
0063     } while (p != end);
0064 }
0065 EXPORT_SYMBOL_GPL(pmd_init);
0066 #endif
0067 
0068 #ifndef __PAGETABLE_PUD_FOLDED
0069 void pud_init(unsigned long addr, unsigned long pagetable)
0070 {
0071     unsigned long *p, *end;
0072 
0073     p = (unsigned long *)addr;
0074     end = p + PTRS_PER_PUD;
0075 
0076     do {
0077         p[0] = pagetable;
0078         p[1] = pagetable;
0079         p[2] = pagetable;
0080         p[3] = pagetable;
0081         p[4] = pagetable;
0082         p += 8;
0083         p[-3] = pagetable;
0084         p[-2] = pagetable;
0085         p[-1] = pagetable;
0086     } while (p != end);
0087 }
0088 #endif
0089 
0090 pmd_t mk_pmd(struct page *page, pgprot_t prot)
0091 {
0092     pmd_t pmd;
0093 
0094     pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot);
0095 
0096     return pmd;
0097 }
0098 
0099 void set_pmd_at(struct mm_struct *mm, unsigned long addr,
0100         pmd_t *pmdp, pmd_t pmd)
0101 {
0102     *pmdp = pmd;
0103 }
0104 
0105 void __init pagetable_init(void)
0106 {
0107     unsigned long vaddr;
0108     pgd_t *pgd_base;
0109 
0110     /* Initialize the entire pgd.  */
0111     pgd_init((unsigned long)swapper_pg_dir);
0112 #ifndef __PAGETABLE_PUD_FOLDED
0113     pud_init((unsigned long)invalid_pud_table, (unsigned long)invalid_pmd_table);
0114 #endif
0115 #ifndef __PAGETABLE_PMD_FOLDED
0116     pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
0117 #endif
0118     pgd_base = swapper_pg_dir;
0119     /*
0120      * Fixed mappings:
0121      */
0122     vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
0123     fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
0124 }