1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2020 Loongson Technology Corporation Limited 4 */ 5#include <linux/export.h> 6#include <linux/init.h> 7#include <linux/mm.h> 8#include <asm/fixmap.h> 9#include <asm/pgtable.h> 10#include <asm/pgalloc.h> 11#include <asm/tlbflush.h> 12 13void pgd_init(unsigned long page) 14{ 15 unsigned long *p, *end; 16 unsigned long entry; 17 18#if !defined(__PAGETABLE_PUD_FOLDED) 19 entry = (unsigned long)invalid_pud_table; 20#elif !defined(__PAGETABLE_PMD_FOLDED) 21 entry = (unsigned long)invalid_pmd_table; 22#else 23 entry = (unsigned long)invalid_pte_table; 24#endif 25 26 p = (unsigned long *) page; 27 end = p + PTRS_PER_PGD; 28 29 do { 30 p[0] = entry; 31 p[1] = entry; 32 p[2] = entry; 33 p[3] = entry; 34 p[4] = entry; 35 p += 8; 36 p[-3] = entry; 37 p[-2] = entry; 38 p[-1] = entry; 39 } while (p != end); 40} 41EXPORT_SYMBOL_GPL(pgd_init); 42 43#ifndef __PAGETABLE_PMD_FOLDED 44void pmd_init(unsigned long addr, unsigned long pagetable) 45{ 46 unsigned long *p, *end; 47 48 p = (unsigned long *) addr; 49 end = p + PTRS_PER_PMD; 50 51 do { 52 p[0] = pagetable; 53 p[1] = pagetable; 54 p[2] = pagetable; 55 p[3] = pagetable; 56 p[4] = pagetable; 57 p += 8; 58 p[-3] = pagetable; 59 p[-2] = pagetable; 60 p[-1] = pagetable; 61 } while (p != end); 62} 63EXPORT_SYMBOL_GPL(pmd_init); 64#endif 65 66#ifndef __PAGETABLE_PUD_FOLDED 67void pud_init(unsigned long addr, unsigned long pagetable) 68{ 69 unsigned long *p, *end; 70 71 p = (unsigned long *)addr; 72 end = p + PTRS_PER_PUD; 73 74 do { 75 p[0] = pagetable; 76 p[1] = pagetable; 77 p[2] = pagetable; 78 p[3] = pagetable; 79 p[4] = pagetable; 80 p += 8; 81 p[-3] = pagetable; 82 p[-2] = pagetable; 83 p[-1] = pagetable; 84 } while (p != end); 85} 86#endif 87 88pmd_t mk_pmd(struct page *page, pgprot_t prot) 89{ 90 pmd_t pmd; 91 92 pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot); 93 94 return pmd; 95} 96 97void set_pmd_at(struct mm_struct *mm, unsigned long addr, 98 pmd_t *pmdp, pmd_t pmd) 99{ 100 *pmdp = pmd; 101 flush_tlb_all(); 102} 103 104void __init pagetable_init(void) 105{ 106 unsigned long vaddr; 107 108 /* Initialize the entire pgd. */ 109 pgd_init((unsigned long)swapper_pg_dir); 110 pgd_init((unsigned long)invalid_pg_dir); 111#ifndef __PAGETABLE_PUD_FOLDED 112 pud_init((unsigned long)invalid_pud_table, (unsigned long)invalid_pmd_table); 113#endif 114#ifndef __PAGETABLE_PMD_FOLDED 115 pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); 116#endif 117 /* 118 * Fixed mappings: 119 */ 120 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; 121} 122