0001
0002
0003
0004
0005
0006
0007
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
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
0121
0122 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
0123 fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
0124 }