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 12bd5ff066SMike Rapoport #include <asm-generic/pgalloc.h> /* for pte_{alloc,free}_one */ 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 void pgd_free(struct mm_struct *mm, pgd_t *pgd) 46013de2d6SGuo Ren { 47013de2d6SGuo Ren free_pages((unsigned long)pgd, PGD_ORDER); 48013de2d6SGuo Ren } 49013de2d6SGuo Ren 50013de2d6SGuo Ren static inline pgd_t *pgd_alloc(struct mm_struct *mm) 51013de2d6SGuo Ren { 52013de2d6SGuo Ren pgd_t *ret; 53013de2d6SGuo Ren pgd_t *init; 54013de2d6SGuo Ren 55013de2d6SGuo Ren ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); 56013de2d6SGuo Ren if (ret) { 57013de2d6SGuo Ren init = pgd_offset(&init_mm, 0UL); 58013de2d6SGuo Ren pgd_init((unsigned long *)ret); 59013de2d6SGuo Ren memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, 60013de2d6SGuo Ren (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 61013de2d6SGuo Ren /* prevent out of order excute */ 62013de2d6SGuo Ren smp_mb(); 63013de2d6SGuo Ren #ifdef CONFIG_CPU_NEED_TLBSYNC 64013de2d6SGuo Ren dcache_wb_range((unsigned int)ret, 65013de2d6SGuo Ren (unsigned int)(ret + PTRS_PER_PGD)); 66013de2d6SGuo Ren #endif 67013de2d6SGuo Ren } 68013de2d6SGuo Ren 69013de2d6SGuo Ren return ret; 70013de2d6SGuo Ren } 71013de2d6SGuo Ren 72013de2d6SGuo Ren #define __pte_free_tlb(tlb, pte, address) \ 73013de2d6SGuo Ren do { \ 74013de2d6SGuo Ren pgtable_page_dtor(pte); \ 75013de2d6SGuo Ren tlb_remove_page(tlb, pte); \ 76013de2d6SGuo Ren } while (0) 77013de2d6SGuo Ren 78013de2d6SGuo Ren #define check_pgt_cache() do {} while (0) 79013de2d6SGuo Ren 80013de2d6SGuo Ren extern void pagetable_init(void); 81013de2d6SGuo Ren extern void pre_mmu_init(void); 82013de2d6SGuo Ren extern void pre_trap_init(void); 83013de2d6SGuo Ren 84013de2d6SGuo Ren #endif /* __ASM_CSKY_PGALLOC_H */ 85