1013de2d6SGuo Ren /* SPDX-License-Identifier: GPL-2.0 */ 2013de2d6SGuo Ren // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3013de2d6SGuo Ren 4013de2d6SGuo Ren #ifndef __ASM_CSKY_PGALLOC_H 5013de2d6SGuo Ren #define __ASM_CSKY_PGALLOC_H 6013de2d6SGuo Ren 7013de2d6SGuo Ren #include <linux/highmem.h> 8013de2d6SGuo Ren #include <linux/mm.h> 9013de2d6SGuo Ren #include <linux/sched.h> 10013de2d6SGuo Ren 11bd5ff066SMike Rapoport #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL 12f9cb654cSMike Rapoport #include <asm-generic/pgalloc.h> 13bd5ff066SMike Rapoport 14013de2d6SGuo Ren static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 15013de2d6SGuo Ren pte_t *pte) 16013de2d6SGuo Ren { 17013de2d6SGuo Ren set_pmd(pmd, __pmd(__pa(pte))); 18013de2d6SGuo Ren } 19013de2d6SGuo Ren 20013de2d6SGuo Ren static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 21013de2d6SGuo Ren pgtable_t pte) 22013de2d6SGuo Ren { 23013de2d6SGuo Ren set_pmd(pmd, __pmd(__pa(page_address(pte)))); 24013de2d6SGuo Ren } 25013de2d6SGuo Ren 26013de2d6SGuo Ren #define pmd_pgtable(pmd) pmd_page(pmd) 27013de2d6SGuo Ren 28013de2d6SGuo Ren extern void pgd_init(unsigned long *p); 29013de2d6SGuo Ren 302a60aa14SGuo Ren static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 31013de2d6SGuo Ren { 32013de2d6SGuo Ren pte_t *pte; 332a60aa14SGuo Ren unsigned long i; 34013de2d6SGuo Ren 352a60aa14SGuo Ren pte = (pte_t *) __get_free_page(GFP_KERNEL); 362a60aa14SGuo Ren if (!pte) 372a60aa14SGuo Ren return NULL; 382a60aa14SGuo Ren 392a60aa14SGuo Ren for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++) 402a60aa14SGuo Ren (pte + i)->pte_low = _PAGE_GLOBAL; 41013de2d6SGuo Ren 42013de2d6SGuo Ren return pte; 43013de2d6SGuo Ren } 44013de2d6SGuo Ren 45013de2d6SGuo Ren static inline pgd_t *pgd_alloc(struct mm_struct *mm) 46013de2d6SGuo Ren { 47013de2d6SGuo Ren pgd_t *ret; 48013de2d6SGuo Ren pgd_t *init; 49013de2d6SGuo Ren 50013de2d6SGuo Ren ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); 51013de2d6SGuo Ren if (ret) { 52013de2d6SGuo Ren init = pgd_offset(&init_mm, 0UL); 53013de2d6SGuo Ren pgd_init((unsigned long *)ret); 54013de2d6SGuo Ren memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, 55013de2d6SGuo Ren (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 56013de2d6SGuo Ren /* prevent out of order excute */ 57013de2d6SGuo Ren smp_mb(); 58013de2d6SGuo Ren #ifdef CONFIG_CPU_NEED_TLBSYNC 59013de2d6SGuo Ren dcache_wb_range((unsigned int)ret, 60013de2d6SGuo Ren (unsigned int)(ret + PTRS_PER_PGD)); 61013de2d6SGuo Ren #endif 62013de2d6SGuo Ren } 63013de2d6SGuo Ren 64013de2d6SGuo Ren return ret; 65013de2d6SGuo Ren } 66013de2d6SGuo Ren 67013de2d6SGuo Ren #define __pte_free_tlb(tlb, pte, address) \ 68013de2d6SGuo Ren do { \ 69b4ed71f5SMark Rutland pgtable_pte_page_dtor(pte); \ 70013de2d6SGuo Ren tlb_remove_page(tlb, pte); \ 71013de2d6SGuo Ren } while (0) 72013de2d6SGuo Ren 73013de2d6SGuo Ren extern void pagetable_init(void); 74*0c8a32eeSGuo Ren extern void mmu_init(unsigned long min_pfn, unsigned long max_pfn); 75013de2d6SGuo Ren extern void pre_trap_init(void); 76013de2d6SGuo Ren 77013de2d6SGuo Ren #endif /* __ASM_CSKY_PGALLOC_H */ 78