18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 38c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 48c2ecf20Sopenharmony_ci * for more details. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2003 by Ralf Baechle 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/mm.h> 108c2ecf20Sopenharmony_ci#include <linux/memblock.h> 118c2ecf20Sopenharmony_ci#include <linux/highmem.h> 128c2ecf20Sopenharmony_ci#include <asm/fixmap.h> 138c2ecf20Sopenharmony_ci#include <asm/pgalloc.h> 148c2ecf20Sopenharmony_ci#include <asm/tlbflush.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_civoid pgd_init(unsigned long page) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci unsigned long *p = (unsigned long *) page; 198c2ecf20Sopenharmony_ci int i; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { 228c2ecf20Sopenharmony_ci p[i + 0] = (unsigned long) invalid_pte_table; 238c2ecf20Sopenharmony_ci p[i + 1] = (unsigned long) invalid_pte_table; 248c2ecf20Sopenharmony_ci p[i + 2] = (unsigned long) invalid_pte_table; 258c2ecf20Sopenharmony_ci p[i + 3] = (unsigned long) invalid_pte_table; 268c2ecf20Sopenharmony_ci p[i + 4] = (unsigned long) invalid_pte_table; 278c2ecf20Sopenharmony_ci p[i + 5] = (unsigned long) invalid_pte_table; 288c2ecf20Sopenharmony_ci p[i + 6] = (unsigned long) invalid_pte_table; 298c2ecf20Sopenharmony_ci p[i + 7] = (unsigned long) invalid_pte_table; 308c2ecf20Sopenharmony_ci } 318c2ecf20Sopenharmony_ci} 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#if defined(CONFIG_TRANSPARENT_HUGEPAGE) 348c2ecf20Sopenharmony_cipmd_t mk_pmd(struct page *page, pgprot_t prot) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci pmd_t pmd; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci return pmd; 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_civoid set_pmd_at(struct mm_struct *mm, unsigned long addr, 458c2ecf20Sopenharmony_ci pmd_t *pmdp, pmd_t pmd) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci *pmdp = pmd; 488c2ecf20Sopenharmony_ci flush_tlb_all(); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci#endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */ 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_civoid __init pagetable_init(void) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci unsigned long vaddr; 558c2ecf20Sopenharmony_ci pgd_t *pgd_base; 568c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 578c2ecf20Sopenharmony_ci pgd_t *pgd; 588c2ecf20Sopenharmony_ci p4d_t *p4d; 598c2ecf20Sopenharmony_ci pud_t *pud; 608c2ecf20Sopenharmony_ci pmd_t *pmd; 618c2ecf20Sopenharmony_ci pte_t *pte; 628c2ecf20Sopenharmony_ci#endif 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* Initialize the entire pgd. */ 658c2ecf20Sopenharmony_ci pgd_init((unsigned long)swapper_pg_dir); 668c2ecf20Sopenharmony_ci pgd_init((unsigned long)swapper_pg_dir 678c2ecf20Sopenharmony_ci + sizeof(pgd_t) * USER_PTRS_PER_PGD); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci pgd_base = swapper_pg_dir; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* 728c2ecf20Sopenharmony_ci * Fixed mappings: 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci vaddr = __fix_to_virt(__end_of_fixed_addresses - 1); 758c2ecf20Sopenharmony_ci fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 788c2ecf20Sopenharmony_ci /* 798c2ecf20Sopenharmony_ci * Permanent kmaps: 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ci vaddr = PKMAP_BASE; 828c2ecf20Sopenharmony_ci fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci pgd = swapper_pg_dir + pgd_index(vaddr); 858c2ecf20Sopenharmony_ci p4d = p4d_offset(pgd, vaddr); 868c2ecf20Sopenharmony_ci pud = pud_offset(p4d, vaddr); 878c2ecf20Sopenharmony_ci pmd = pmd_offset(pud, vaddr); 888c2ecf20Sopenharmony_ci pte = pte_offset_kernel(pmd, vaddr); 898c2ecf20Sopenharmony_ci pkmap_page_table = pte; 908c2ecf20Sopenharmony_ci#endif 918c2ecf20Sopenharmony_ci} 92