|
@@ -201,6 +201,46 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval)
|
|
|
set_pte_vaddr_pud(pud_page, vaddr, pteval);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Create large page table mappings for a range of physical addresses.
|
|
|
+ */
|
|
|
+static void __init __init_extra_mapping(unsigned long phys, unsigned long size,
|
|
|
+ pgprot_t prot)
|
|
|
+{
|
|
|
+ pgd_t *pgd;
|
|
|
+ pud_t *pud;
|
|
|
+ pmd_t *pmd;
|
|
|
+
|
|
|
+ BUG_ON((phys & ~PMD_MASK) || (size & ~PMD_MASK));
|
|
|
+ for (; size; phys += PMD_SIZE, size -= PMD_SIZE) {
|
|
|
+ pgd = pgd_offset_k((unsigned long)__va(phys));
|
|
|
+ if (pgd_none(*pgd)) {
|
|
|
+ pud = (pud_t *) spp_getpage();
|
|
|
+ set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
|
|
|
+ _PAGE_USER));
|
|
|
+ }
|
|
|
+ pud = pud_offset(pgd, (unsigned long)__va(phys));
|
|
|
+ if (pud_none(*pud)) {
|
|
|
+ pmd = (pmd_t *) spp_getpage();
|
|
|
+ set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
|
|
|
+ _PAGE_USER));
|
|
|
+ }
|
|
|
+ pmd = pmd_offset(pud, phys);
|
|
|
+ BUG_ON(!pmd_none(*pmd));
|
|
|
+ set_pmd(pmd, __pmd(phys | pgprot_val(prot)));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void __init init_extra_mapping_wb(unsigned long phys, unsigned long size)
|
|
|
+{
|
|
|
+ __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE);
|
|
|
+}
|
|
|
+
|
|
|
+void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
|
|
|
+{
|
|
|
+ __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE_NOCACHE);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* The head.S code sets up the kernel high mapping:
|
|
|
*
|