18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef M68K_MCF_PGALLOC_H 38c2ecf20Sopenharmony_ci#define M68K_MCF_PGALLOC_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm/tlb.h> 68c2ecf20Sopenharmony_ci#include <asm/tlbflush.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ciextern inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 98c2ecf20Sopenharmony_ci{ 108c2ecf20Sopenharmony_ci free_page((unsigned long) pte); 118c2ecf20Sopenharmony_ci} 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciextern const char bad_pmd_string[]; 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ciextern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci unsigned long page = __get_free_page(GFP_DMA); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci if (!page) 208c2ecf20Sopenharmony_ci return NULL; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci memset((void *)page, 0, PAGE_SIZE); 238c2ecf20Sopenharmony_ci return (pte_t *) (page); 248c2ecf20Sopenharmony_ci} 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ciextern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci return (pmd_t *) pgd; 298c2ecf20Sopenharmony_ci} 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define pmd_populate(mm, pmd, pte) (pmd_val(*pmd) = (unsigned long)(pte)) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define pmd_populate_kernel pmd_populate 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define pmd_pgtable(pmd) pfn_to_virt(pmd_val(pmd) >> PAGE_SHIFT) 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pgtable, 388c2ecf20Sopenharmony_ci unsigned long address) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci struct page *page = virt_to_page(pgtable); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci pgtable_pte_page_dtor(page); 438c2ecf20Sopenharmony_ci __free_page(page); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic inline pgtable_t pte_alloc_one(struct mm_struct *mm) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci struct page *page = alloc_pages(GFP_DMA, 0); 498c2ecf20Sopenharmony_ci pte_t *pte; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci if (!page) 528c2ecf20Sopenharmony_ci return NULL; 538c2ecf20Sopenharmony_ci if (!pgtable_pte_page_ctor(page)) { 548c2ecf20Sopenharmony_ci __free_page(page); 558c2ecf20Sopenharmony_ci return NULL; 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci pte = page_address(page); 598c2ecf20Sopenharmony_ci clear_page(pte); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci return pte; 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic inline void pte_free(struct mm_struct *mm, pgtable_t pgtable) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci struct page *page = virt_to_page(pgtable); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci pgtable_pte_page_dtor(page); 698c2ecf20Sopenharmony_ci __free_page(page); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* 738c2ecf20Sopenharmony_ci * In our implementation, each pgd entry contains 1 pmd that is never allocated 748c2ecf20Sopenharmony_ci * or freed. pgd_present is always 1, so this should never be called. -NL 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_ci#define pmd_free(mm, pmd) BUG() 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistatic inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci free_page((unsigned long) pgd); 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic inline pgd_t *pgd_alloc(struct mm_struct *mm) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci pgd_t *new_pgd; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN); 888c2ecf20Sopenharmony_ci if (!new_pgd) 898c2ecf20Sopenharmony_ci return NULL; 908c2ecf20Sopenharmony_ci memcpy(new_pgd, swapper_pg_dir, PTRS_PER_PGD * sizeof(pgd_t)); 918c2ecf20Sopenharmony_ci memset(new_pgd, 0, PAGE_OFFSET >> PGDIR_SHIFT); 928c2ecf20Sopenharmony_ci return new_pgd; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#endif /* M68K_MCF_PGALLOC_H */ 96