18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifndef __ASM_CSKY_PGALLOC_H 58c2ecf20Sopenharmony_ci#define __ASM_CSKY_PGALLOC_H 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/highmem.h> 88c2ecf20Sopenharmony_ci#include <linux/mm.h> 98c2ecf20Sopenharmony_ci#include <linux/sched.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL 128c2ecf20Sopenharmony_ci#include <asm-generic/pgalloc.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 158c2ecf20Sopenharmony_ci pte_t *pte) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci set_pmd(pmd, __pmd(__pa(pte))); 188c2ecf20Sopenharmony_ci} 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistatic inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 218c2ecf20Sopenharmony_ci pgtable_t pte) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci set_pmd(pmd, __pmd(__pa(page_address(pte)))); 248c2ecf20Sopenharmony_ci} 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define pmd_pgtable(pmd) pmd_page(pmd) 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ciextern void pgd_init(unsigned long *p); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci pte_t *pte; 338c2ecf20Sopenharmony_ci unsigned long i; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci pte = (pte_t *) __get_free_page(GFP_KERNEL); 368c2ecf20Sopenharmony_ci if (!pte) 378c2ecf20Sopenharmony_ci return NULL; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++) 408c2ecf20Sopenharmony_ci (pte + i)->pte_low = _PAGE_GLOBAL; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci return pte; 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic inline pgd_t *pgd_alloc(struct mm_struct *mm) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci pgd_t *ret; 488c2ecf20Sopenharmony_ci pgd_t *init; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); 518c2ecf20Sopenharmony_ci if (ret) { 528c2ecf20Sopenharmony_ci init = pgd_offset(&init_mm, 0UL); 538c2ecf20Sopenharmony_ci pgd_init((unsigned long *)ret); 548c2ecf20Sopenharmony_ci memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, 558c2ecf20Sopenharmony_ci (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 568c2ecf20Sopenharmony_ci /* prevent out of order excute */ 578c2ecf20Sopenharmony_ci smp_mb(); 588c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_NEED_TLBSYNC 598c2ecf20Sopenharmony_ci dcache_wb_range((unsigned int)ret, 608c2ecf20Sopenharmony_ci (unsigned int)(ret + PTRS_PER_PGD)); 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci return ret; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define __pte_free_tlb(tlb, pte, address) \ 688c2ecf20Sopenharmony_cido { \ 698c2ecf20Sopenharmony_ci pgtable_pte_page_dtor(pte); \ 708c2ecf20Sopenharmony_ci tlb_remove_page(tlb, pte); \ 718c2ecf20Sopenharmony_ci} while (0) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ciextern void pagetable_init(void); 748c2ecf20Sopenharmony_ciextern void pre_mmu_init(void); 758c2ecf20Sopenharmony_ciextern void pre_trap_init(void); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#endif /* __ASM_CSKY_PGALLOC_H */ 78