162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 362306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 462306a36Sopenharmony_ci * for more details. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2003 by Ralf Baechle 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#include <linux/init.h> 962306a36Sopenharmony_ci#include <linux/mm.h> 1062306a36Sopenharmony_ci#include <linux/memblock.h> 1162306a36Sopenharmony_ci#include <linux/highmem.h> 1262306a36Sopenharmony_ci#include <asm/fixmap.h> 1362306a36Sopenharmony_ci#include <asm/pgalloc.h> 1462306a36Sopenharmony_ci#include <asm/tlbflush.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_civoid pgd_init(void *addr) 1762306a36Sopenharmony_ci{ 1862306a36Sopenharmony_ci unsigned long *p = (unsigned long *)addr; 1962306a36Sopenharmony_ci int i; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { 2262306a36Sopenharmony_ci p[i + 0] = (unsigned long) invalid_pte_table; 2362306a36Sopenharmony_ci p[i + 1] = (unsigned long) invalid_pte_table; 2462306a36Sopenharmony_ci p[i + 2] = (unsigned long) invalid_pte_table; 2562306a36Sopenharmony_ci p[i + 3] = (unsigned long) invalid_pte_table; 2662306a36Sopenharmony_ci p[i + 4] = (unsigned long) invalid_pte_table; 2762306a36Sopenharmony_ci p[i + 5] = (unsigned long) invalid_pte_table; 2862306a36Sopenharmony_ci p[i + 6] = (unsigned long) invalid_pte_table; 2962306a36Sopenharmony_ci p[i + 7] = (unsigned long) invalid_pte_table; 3062306a36Sopenharmony_ci } 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#if defined(CONFIG_TRANSPARENT_HUGEPAGE) 3462306a36Sopenharmony_cipmd_t mk_pmd(struct page *page, pgprot_t prot) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci pmd_t pmd; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci pmd_val(pmd) = (page_to_pfn(page) << PFN_PTE_SHIFT) | pgprot_val(prot); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci return pmd; 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_civoid set_pmd_at(struct mm_struct *mm, unsigned long addr, 4562306a36Sopenharmony_ci pmd_t *pmdp, pmd_t pmd) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci *pmdp = pmd; 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci#endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_civoid __init pagetable_init(void) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci unsigned long vaddr; 5462306a36Sopenharmony_ci pgd_t *pgd_base; 5562306a36Sopenharmony_ci#ifdef CONFIG_HIGHMEM 5662306a36Sopenharmony_ci pgd_t *pgd; 5762306a36Sopenharmony_ci p4d_t *p4d; 5862306a36Sopenharmony_ci pud_t *pud; 5962306a36Sopenharmony_ci pmd_t *pmd; 6062306a36Sopenharmony_ci pte_t *pte; 6162306a36Sopenharmony_ci#endif 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci /* Initialize the entire pgd. */ 6462306a36Sopenharmony_ci pgd_init(swapper_pg_dir); 6562306a36Sopenharmony_ci pgd_init(&swapper_pg_dir[USER_PTRS_PER_PGD]); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci pgd_base = swapper_pg_dir; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci /* 7062306a36Sopenharmony_ci * Fixed mappings: 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_ci vaddr = __fix_to_virt(__end_of_fixed_addresses - 1); 7362306a36Sopenharmony_ci fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci#ifdef CONFIG_HIGHMEM 7662306a36Sopenharmony_ci /* 7762306a36Sopenharmony_ci * Permanent kmaps: 7862306a36Sopenharmony_ci */ 7962306a36Sopenharmony_ci vaddr = PKMAP_BASE; 8062306a36Sopenharmony_ci fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci pgd = swapper_pg_dir + pgd_index(vaddr); 8362306a36Sopenharmony_ci p4d = p4d_offset(pgd, vaddr); 8462306a36Sopenharmony_ci pud = pud_offset(p4d, vaddr); 8562306a36Sopenharmony_ci pmd = pmd_offset(pud, vaddr); 8662306a36Sopenharmony_ci pte = pte_offset_kernel(pmd, vaddr); 8762306a36Sopenharmony_ci pkmap_page_table = pte; 8862306a36Sopenharmony_ci#endif 8962306a36Sopenharmony_ci} 90